Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC claims a friend function to be overloaded, ambiguous call, clang compiles

Tags:

c++

gcc

clang

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?

like image 796
hpohl Avatar asked Apr 13 '13 12:04

hpohl


1 Answers

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++

like image 84
Stefano Falasca Avatar answered Nov 15 '22 06:11

Stefano Falasca