Search code examples
c++templatesstructlanguage-lawyername-lookup

Why does the C struct hack not work for C++ template declarations?


C has this fun hack where one name can be used to declare both a type and a function:

struct foo {};
void foo(void);

Now, any time I write foo, the compiler assumes I mean the function unless I prefix it with struct:

foo();  // call void foo(void)
struct foo bar;  // declare variable of type struct foo

This works great in C++ even with namespaces and nesting! But it doesn't work with templates:

template <typename> void bar(void);
template <typename> struct bar {};
// error: conflicting declaration of template struct bar
// previous declaration: template void bar()

Why?

We already get to deal with disambiguators in dependent contexts:

typename foo<A>::b();
foo<A>::template b<C>();

It doesn't seem much of a stretch to apply the regular rules to ambiguous template names of this kind.

Suppose that having the same name is important to me. Could I somehow make this work?


Solution

  • The wording is in temp.pre-7:

    A class template shall not have the same name as any other template, class, function, variable, enumeration, enumerator, namespace, or type in the same scope ([basic.scope]), except as specified in [temp.class.spec]...

    None of the points in temp.class.spec conflict with this example.

    So, as it stands, you can't have the same name for a class template and a function template.