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;
}
Run Code Online (Sandbox Code Playgroud)
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);
^
Run Code Online (Sandbox Code Playgroud)
我想知道为什么海湾合作委员会声称f超载.所以我猜这是一个GCC错误.
哪个编译器是对的?
C++ 标准中不再存在友元注入,请参阅此以获取有关此内容的信息。然而,由于在 struct b 内部声明的友元函数“作用”于“b”类型的参数,因此该函数是通过 ADL(参数相关查找)找到的。当这种情况发生时,会声明两个具有相同签名的不同函数,并且编译器会抱怨。
这可能就是你的意思:
template <template <typename> class P>
struct b {
template <class, template <typename> class FriendP>
friend void f(b<FriendP> from){};
};
Run Code Online (Sandbox Code Playgroud)
但不要在实际代码中使用它,因为正如您所见,“重复函数”问题很容易出现(正确使用命名空间可以在这方面有所帮助)。
代码可以在这里进行测试
关于模板友元函数的使用(以及为什么需要它们的一个很好的现实例子)的一个很好的参考可以在Effective c++的第46项中找到