明确的专长不能是朋友声明

Vah*_*yan 5 c++ templates friend-function explicit-specialization

代码

template <typename T>
void foo(const T& t)
{}

template <typename T>
class A
{
    template <>
    friend void foo<T>(const T& t)
    {}
};
Run Code Online (Sandbox Code Playgroud)

给出编译错误

"defining explicit specialization ‘foo<T>’ in friend declaration friend void foo<T>(const T& t)"
Run Code Online (Sandbox Code Playgroud)

用gcc和

"error C3637: 'A<int>::foo' : a friend function definition cannot be a specialization of a unction template"
Run Code Online (Sandbox Code Playgroud)

在VS2013中编译时

我了解该标准是这样说的,但是为什么呢?我想了解原因(在幕后),有很多文章写着“显式专业化不能成为朋友声明。”,但我不明白为什么。有任何想法吗?

Col*_*mbo 6

第一次(也可能是唯一一次)在类模板中声明显式特化意味着显式特化仅在模板被实例化后才“存在”——无论声明是否依赖于模板参数。这会产生许多问题,并会导致在各种情况下违反 ODR,其中许多可能是格式错误的 NDR;主要是因为@dyp在评论中提到的那段,[temp.expl.spec]/6

此外,没有外部声明的类中的友元函数定义使该函数只能通过 ADL 调用。显然,如果显式特化仅在调用具有关联参数类型时适用,那将绝对是荒谬的——再说一次,更不用说违反 ODR 了。

这些和其他原因使得这样的构造过于复杂也允许,虽然不是很有益:您可以简单地做的是将特化添加为 a friend,而不以任何方式表明该特化是实例化的还是显式特化的。

friend void foo<T>(const T&);
Run Code Online (Sandbox Code Playgroud)

然后可以在命名空间范围中添加任何显式特化。