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.