当前位置: 首页 > 知识库问答 >
问题:

类模板中可见的友元函数名称

曾洲
2023-03-14

考虑以下示例:

template <typename T>
class C
{
    public:
        friend void f() {}
        friend void f(C<T>) {}
};

C<int> c;

void g(C<int>* p)
{
     f(); 
     f(*p);
}

使用GCC 5.2编译会引发以下编译错误:

no matching function for call to 'f()'

但是标准在14.6.5中说:

友元类或函数可以在类模板中声明。当模板被实例化时,其朋友的名称被视为在实例化点显式声明了专门化。

为什么编译失败?在GCC 3.4中,通过。

共有2个答案

卜高超
2023-03-14

f()的调用与类C无关,因此在重载解析中不使用它的朋友。

在另一个调用f(*p)中,参数是类类型的,因此会检查类和类的命名空间是否可能的候选者。这样编译器就会找到两个f函数并使用重载解析来选择正确的一个。

陆昊
2023-03-14

只有通过参数相关名称查找(ADL)才能找到f。第二个调用是编译的,因为作为参数传递的p的pointee类型是C

只需在您的[临时注入]后立即查看报价/2:

与非模板类一样,类模板专门化的命名空间作用域友元函数的名称在普通查找过程中不可见,除非在命名空间作用域中显式声明(11.3)。此类名称可在关联类规则(3.4.2)下找到141

无论是在声明模板还是在实例化模板时,友元声明都不会将新名称引入任何作用域。

 类似资料:
  • 我想知道如果函数的模板参数包括但不限于类的模板参数,如何使函数成为类的朋友并在类外定义函数。 例如,我有以下模板类和模板朋友函数: 如果我编译: 我会得到以下链接器错误:

  • 我有一个类模板和一个函数模板定义了一个,它引用要绑定到的模板类型。 我想要的是将< code>make_obj函数声明为< code>friend,这样它可以创建< code>Obj的,但是其他人不能(除了通过copy ctor)。 我尝试了几个朋友声明,包括 和 后者是使< code>make_obj的所有模板实例化成为< code>Obj类的朋友的不太理想的尝试。然而,在这两种情况下,我得到相

  • 我试图使乘法运算符成为名为TVector3的模板类的朋友。我读过,我可以在类声明中声明朋友函数之前,对其进行前向声明,但我这样做的尝试是徒劳的。我知道我可以简单地定义friend函数而不是声明它,但我希望它能与前向声明技术一起工作。 特别是,我试图为我的案例实施这个解决方案。我发现这篇文章也是David Rodriguez给出的解决方案(第三个版本),但我不知道我做错了什么。 我使用'g temp

  • 是否允许在友元声明中为模板参数提供默认值? Visual Studio 2015似乎允许这样做。gcc拒绝了。我在cppreference页面上找不到任何内容。

  • 我正在学习一个视频教程,我想声明一个模板函数作为模板类的朋友。我不知道为什么代码会抛出错误。 编译器抛出错误。 错误: templates\u friends\u 38。cpp:在“void doSomething2(T)[T=int]”的实例化中:templates\u friends\u 38。cpp:40:19:此处需要templates\u friends\u 38。cpp:32:9:错误

  • 我遇到了以下代码,其行为是由所有GCC、Clang和MSVC商定的: 现场演示:https://godbolt.org/z/hK6xhesKM 在全局命名空间中声明,并带有推断的返回类型<代码>S 我所期望的是,当用〈code〉U=double〈code〉实例化〈code〉S〈code〉时,它对〈code〉foo()〈code〉的定义被放入全局命名空间,并且〈code〉U〈code〉被替换,因为友