在类模板中定义的友元函数定义的范围是什么/在哪里?

时间:2012-11-08 16:05:22

标签: c++

  

可能重复:
  What’s the scope of inline friend functions?

考虑简单程序:

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

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

上面的代码打破了ODR规则,我想知道为什么? ,还有函数范围bar

3 个答案:

答案 0 :(得分: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>();
}

答案 1 :(得分:1)

因为你的代码定义了两次自由函数void bar(),或者更确切地说,你的模板为每个实例化生成了一个名为void bar()的新函数,它恰好每次具有完全相同的签名,因此你有多个具有相同签名的功能,这违反了ODR。

手头的技术称为“朋友名称注入”,因为您在周围的命名空间中注入了一个名称。

答案 2 :(得分:0)

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