海湾合作委员会声称一个朋友的功能是超载,暧昧的电话,铿锵编译

时间:2013-04-13 12:35:45

标签: 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)编译好,而GCC 4.8拒绝它:

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);
                 ^

我想知道为什么海湾合作委员会要求f超载。所以我猜这是一个GCC错误。

哪种编译器是对的?

1 个答案:

答案 0 :(得分:1)

c ++标准中不再存在Friend注入,有关此信息,请参阅this。但是,由于在struct b中声明的friend函数“作用”了类型为“b”的参数,因此通过ADL(依赖于参数的查找)找到该函数。当发生这种情况时,会声明具有相同签名的2个不同函数,并且编译器会抱怨。

这可能就是你的意思:

template <template <typename> class P>
struct b {
    template <class, template <typename> class FriendP>
    friend void f(b<FriendP> from){};
};

但不要在实际代码中使用它,因为正如您所见,“重复功能”问题很容易出现(正确使用命名空间可能对此有所帮助)。

可以测试代码here

有效的c ++项目46中可以找到模板友好函数的使用(以及需要它们的真实例子)的一个很好的参考。