Why is <> required when specifying a template class that has default values ​​for all of its template parameters?

Is there a good reason why <> is required when specifying a template class that has default values ​​for all of its template parameters?

eg.

 #include <iostream> template<typename T = int> class C { public: T obj = 0; }; int main() { C c1; // Error on almost all compilers (see note below) C<> c2; std::cout << c1.obj << " " << c2.obj << std::endl; return 0; } 

The disadvantage of this example is that if you have a class that is already used in different places, and you later reorganize it as a class template with default parameters for its template arguments, then you need to add <> to all the places that use class.

Note: it seems that the latest HECC (7.0.1) GCC accepts the syntax without <> . In earlier versions there is not a single version of Clang. Is this a bug in the latest GCC HEAD? Or perhaps the C ++ 17 standard now accepts syntax without <> , and GCC is just ahead?

+7
source share
1 answer

In C ++ 17, this is well-formed:

 C c1{}; 

due to the output for class templates . We synthesized a function for each constructor (and a subtraction guide) and performed overload resolution:

 template <class T=int> C<T> foo(); template <class T=int> C<T> foo(C<T> const&); template <class T=int> C<T> foo(C<T>&&); 

The first one is a viable overload, while the other two are not, so the output completes successfully, and the C placeholder is replaced by the deduced type C<int> .

However, a grammatically initializer is required in [dcl.type.class.deduct]:

If the placeholder for the inferred type of the class appears as the decl specifier in the specifier-spec-seq of the simple declaration, the init-declarator of this declaration should look like:

Identifier attribute identifier declaration-seq opt

The placeholder is replaced by the return type of the function selected by overload resolution for the subtract class class (13.3.1.8).

But C c; does not contain an initializer, so it does not match grammatically. This is a gcc bug for this. Although it seems strange to categorically ban it. Apparently, this restriction was lifted in Kona, therefore C c; will really be well-formed in C ++ 17. I will update the answer when new formulations come out.


Prior to C ++ 17, a statement was poorly formed simply because C not a type. C and C<> are not the same thing. Particular attention was paid to the presence of all default template parameters. Class types and templates are different and are still treated differently.

+4
source

All Articles