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错误。
哪种编译器是对的?
答案 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中可以找到模板友好函数的使用(以及需要它们的真实例子)的一个很好的参考。