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

Viewed 87

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?

1 Answers

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.

Related