3

可能重复:
内联友元函数的范围是什么?

考虑简单的程序:

template<typename T> struct foo{
friend void bar(){}
};

int main(){
foo<int>(); foo<float>();
}

上面的代码违反了 ODR 规则,我想知道为什么?,还有功能范围在哪里bar

4

3 回答 3

1

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>();
}
于 2012-11-08T16:13:28.743 回答
1

因为您的代码定义了void bar()两次免费函数,或者更确切地说,您的模板为每个实例化生成一个名为 的新函数void bar(),该函数每次都具有完全相同的签名,因此您有多个具有相同签名的函数,这是一种违规行为的 ODR。

手头的技术称为“朋友名称注入”,因为您将名称注入周围的名称空间。

于 2012-11-08T16:17:35.193 回答
0

你已经定义bar你的struct. 这导致barfunc 的双重定义,每个模板实例化一次。Friend应该只是某个实体的声明。实体本身(在您的情况下为 func )应在其他地方定义。用声明替换您的bar定义并在另一个地方定义您的。friend void bar();bar

于 2012-11-08T16:09:01.540 回答