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.
Barry source share