类模板中的友元成员函数定义

Friend member function definition in class templates

本文关键字:成员 函数 定义 友元      更新时间:2023-10-16

无论c++标准有什么要求(98,11,14),下面这段代码都不能在c++和clang++中正确编译:

$ cat foo.cc
template <typename T>
struct foo
{
  friend void bar(){}
};
int main()
{
  foo<int> fi;
  foo<char> fc;
}
例如:

$ clang++-mp-3.7 -std=c++14 foo.cc
foo.cc:4:15: error: redefinition of 'bar'
  friend void bar(){}
              ^
foo.cc:10:13: note: in instantiation of template class 'foo<char>' requested here
  foo<char> fc;
            ^
foo.cc:4:15: note: previous definition is here
  friend void bar(){}
              ^
1 error generated.
我知道我可以通过将bar定义(不是声明)从foo中取出来避免这个问题,我不是在要求解决方法。相反,我想知道发生了什么。所以我有两个问题:
  • 首先,我没有看到在标准中记录或暗示这种行为的地方。我怀疑g++和clang++都不会错,所以我希望它在某个地方被记录/暗示。

  • 第二,这种行为的意义是什么?在类内部定义友元是有价值的(例如,请参阅在类内部或外部定义友元函数有什么区别),那么保持这种行为的价值是什么呢?我的意思是,标准不应该像人们(我)期望的那样接受这种行为吗?

为每个T创建一个新类。因此,foo<int>是一类,foo<char>是另一类。

如果你拿你的例子并展开它,它看起来像这样:

struct foo_int
{
    friend void bar() {}
};
struct foo_char
{
    friend void bar() {}
};

int main()
{
    foo_int fi;
    foo_char fc;
}

通过friend关键字,您定义了一个名为bar的静态全局(命名空间范围)函数。正如你在这里看到的,你做了两次