Home > front end >  class template empty argument list
class template empty argument list

Time:12-08

I understand in C 17, the following syntax is allowed (omitting the argument list).

template<typename T = int>
struct foo {
    using type = T;
};

int main() {
    foo f1; // compiles 
    foo<> f2; // compiles
}

Why is the following not supported? Why can I omit the argument list when declaring an instance, but not when accessing a member type?

int main() {
    foo::type t1; // fails to compile
    foo<>::type t2; // compiles
}

CodePudding user response:

The name foo is the name of a template, not the name of a type. A template is a grammatical construct which generates a variable, function, or type, based on a set of arguments and some prototype (the template definition). That is, a template can generate a type, but the template itself is not a type.

foo is a template. foo<int> is a type, generated from applying int to the parameters of the template foo. foo<> is also a type, applying no arguments to the parameters of the template foo. But foo is just the name of a template.

However, there are certain places where the name of a template for a type can be used in place of a type name. For example, if you're in the definition of foo and refer to foo (such as specifying the name of the constructor or a function parameter or the like), you are referring to the specific foo being instantiated with a specific set of template parameters.

One other place where foo can be used in place of a type name is when creating an object (such as with foo f1;. This uses a process called class template argument deduction, which takes the arguments passed to the constructor and applies them through various processes to figure out what the template arguments should be. foo f1; works because that grammar triggers CTAD, and no arguments given means no template arguments are deduced, but foo's parameters are all defaulted, so that's fine.

foo::type is not grammar which triggers CTAD. Since CTAD is based on arguments to constructors (even if you don't pass any), CTAD only applies to grammar which creates an object from that template. There is no object being created, so CTAD doesn't apply. So foo just names a template, and a template can't have :: applied to it.

  • Related