template <typename T>
class rp {
};
template <template <typename> class P>
struct b {
template <class, template <typename> class FriendP>
friend void f(b<FriendP> from);
};
template <class, template <typename> class P>
void f(b<P> from) {
}
int main() {
b<rp> v;
f<int>(v);
return 0;
}
Clang 3.3 (svn) compiles fine, while GCC 4.8 rejects it:
main.cpp: In function 'int main()':
main.cpp:17:10: error: call of overloaded 'f(b<rp>&)' is ambiguous
f<int>(v);
^
main.cpp:17:10: note: candidates are:
main.cpp:12:6: note: void f(b<P>) [with <template-parameter-1-1> = int; P = rp]
void f(b<P> from) {
^
main.cpp:8:17: note: void f(b<FriendP>) [with <template-parameter-2-1> = int; FriendP = rp; P = rp]
friend void f(b<FriendP> from);
^
I wonder why GCC claims f
to be overloaded. So I guess it's a GCC bug.
Which compiler is right?
Friend injection does no longer exist in the c++ standard, see this for informations about this. However, since the friend function declared inside struct b "acts" on a parameter of type "b", the function is found via ADL (argument-dependant lookup). When this happens 2 different functions having the same signature are declared, and the compiler complains.
This is probably what you meant:
template <template <typename> class P>
struct b {
template <class, template <typename> class FriendP>
friend void f(b<FriendP> from){};
};
but don't use this in real code as it is, since "duplicate function" problems can, as you see, easily arise (proper use of namespaces can be of help with this respect).
The code can be tested here
A good reference for the use (as well as a good real-life example of why they are needed) of template friend functions can be found in item 46 of Effective c++
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