Search code examples
c++templatesfriend

Why can't I declare a type of friend function by template parameter but can with alias


Consider the code:

template <class T>
class Bar {
    int foobar;
    using X = T();
    friend X foo;
};

void foo() {
    Bar<void> bar;
    bar.foobar = 1;
    static_cast<void>(bar);
}

int main() {}

Compiles fine in both gcc and clang. But seemingly equivalent code:

template <class T>
class Bar {
    int foobar;
    friend T foo;
};

void foo() {
    Bar<void()> bar;
    bar.foobar = 1;
    static_cast<void>(bar);
}

int main() {}

causes error in both gcc and clang. How come the template parameter doesn't work here equivalently to alias?


Solution

  • Because T foo is parsed as the declaration of an object, and instantiation of a template cannot change a declaration of an object to a declaration of a function.

    C++ standard/[temp.spec]:

    If a function declaration acquired its function type through a dependent type (17.7.2.1) without using the syntactic form of a function declarator, the program is ill-formed.