Is this code invalid:
template <class T> struct A;
class C {
template <class T> friend void A<T>::foo();
};
In GCC 6.1.0 it says:
error: member 'void A<T>::foo()' declared as friend before type 'A<T>' defined
template <class T> friend void A<T>::foo();
Clang 3.8.0:
warning: dependent nested name specifier 'A<T>::' for friend class declaration
is not supported; turning off access control for 'C' [-Wunsupported-friend]
And Visual Studio 2015 crashes:
fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'f:\dd\vctools\compiler\cxxfe\sl\p1\c\template.cpp', line 8952)
template <class T> friend void A<T>::foo();
More specifically, is A
required to be defined before the friend declaration?
template <class T> struct A;
class C {
static void foo();
template <class T> friend void A<T>::f();
};
template <class T> struct A {
void f() { }
};
If so, why?
If the friend function is a member of another class, you need to use the scope resolution operator ( :: ). For example: class A { public: int f() { } }; class B { friend int A::f(); }; Friends of a base class are not inherited by any classes derived from that base class.
The function is not in the 'scope' of the class to which it has been declared a friend. Friend functions can be a member of a class or a function that is declared outside the scope of class. It cannot be invoked using the object as it is not in the scope of that class.
In object-oriented programming, a friend function, that is a "friend" of a given class, is a function that is given the same access as methods to private and protected data. A friend function is declared by the class that is granting access, so friend functions are part of the class interface, like methods.
A friend function is a function that isn't a member of a class but has access to the class's private and protected members. Friend functions aren't considered class members; they're normal external functions that are given special access privileges.
You refer to A
's member function foo
. This function is not known to exist yet, because you only forward declare A
.
In other words, you'll have to declare A<T>::foo
before C
, as the GCC message tries to tell you (the other two are rather cryptic). This means you have to declare the complete interface of A
before C
, instead of only forward declaring it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With