6

编码

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

template <typename T>
class A
{
    template <>
    friend void foo<T>(const T& t)
    {}
};

给出编译错误

"defining explicit specialization ‘foo<T>’ in friend declaration friend void foo<T>(const T& t)"

当使用 gcc 和

"error C3637: 'A<int>::foo' : a friend function definition cannot be a specialization of a unction template"

在 VS2013 中编译时

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

4

1 回答 1

6

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

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

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

friend void foo<T>(const T&);

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

于 2015-01-04T16:29:52.997 回答