可能重复:
内联友元函数的范围是什么?
考虑简单的程序:
template<typename T> struct foo{
friend void bar(){}
};
int main(){
foo<int>(); foo<float>();
}
上面的代码违反了 ODR 规则,我想知道为什么?,还有功能范围在哪里bar
?
可能重复:
内联友元函数的范围是什么?
考虑简单的程序:
template<typename T> struct foo{
friend void bar(){}
};
int main(){
foo<int>(); foo<float>();
}
上面的代码违反了 ODR 规则,我想知道为什么?,还有功能范围在哪里bar
?
friend
函数不是成员函数;您只需在类中声明友谊,但该函数始终是自由函数。如果您在类模板类中定义它,您最终将定义它的次数与您拥有的模板实例一样多。
我将尝试用代码解释这一点。出于我们的目的,您的代码等效于:
template<typename T> struct foo{
};
template<> struct foo<int>{
friend void bar();
};
void bar() {};
template<> struct foo<double>{
friend void bar();
};
void bar() {};
int main(){
foo<int>(); foo<float>();
}
因为您的代码定义了void bar()
两次免费函数,或者更确切地说,您的模板为每个实例化生成一个名为 的新函数void bar()
,该函数每次都具有完全相同的签名,因此您有多个具有相同签名的函数,这是一种违规行为的 ODR。
手头的技术称为“朋友名称注入”,因为您将名称注入周围的名称空间。
你已经定义了bar
你的struct
. 这导致bar
func 的双重定义,每个模板实例化一次。Friend
应该只是某个实体的声明。实体本身(在您的情况下为 func )应在其他地方定义。用声明替换您的bar
定义并在另一个地方定义您的。friend void bar();
bar