Home > OS >  Default template parameter cannot be used inside another template parameter?
Default template parameter cannot be used inside another template parameter?

Time:12-16

I have a class template with a default value for the template parameter:

template<typename T = int>
class DefaultType : private std::array<T, 5> { };

and since c 17 this can be instantiated like a normal class

DefaultType obj; // equivalent to `DefaultType<>`

The same thing cannot be done if I use this type as an argument for another template:

// error: type/value mismatch at argument 1 in template parameter list for ...
class Foo : public std::vector<DefaultType> { };

yet, the above snippet does compile with DefaultType<>. (godbolt)

what's the reason for that? would a deduction guide help? and what about NTTPs?

CodePudding user response:

This:

DefaultType obj; 

uses CTAD (class template argument deduction) which is available since C 17 and only in certain contexts:

  • any declaration that specifies initialization of a variable and variable template
  • new-expressions
  • function-style cast expressions
  • the type of a non-type template parameter:

To instantiate DefaultType with the default argument in other contexts you still need to write DefaultType<>.

I suppose the reason to have CTAD only in certain contexts is that those are the contexts where you always want an instantiation, but never the template.

  • Related