显式专业化不能是朋友声明

时间:2015-01-04 15:35:36

标签: 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)
    {}
};

给出编译错误

"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中编译时

我明白标准是这样说的,但为什么呢?我想了解原因(引擎盖下) 有很多文章写的&#34;明确的专业化不能成为朋友的声明。&#34;,但我不明白为什么。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

在第一个(也可能是唯一的)时间内在类模板中声明显式特化将意味着显式特化仅仅是&#34;现有的&#34;一旦模板被实例化 - 无论声明是否依赖于模板参数。 这造成了许多问题,并且会在各种情况下导致违反ODR的行为,其中许多可能是不正当的NDR;主要是因为@dyp在评论中提到的段落,[temp.expl.spec] / 6

此外,没有外部声明的类中的朋友函数 definition 使得此函数只能通过ADL调用。显然,如果显式专门化仅在调用关联参数类型时适用,那绝对是荒谬的 - 再次,更不用说违反ODR了。

这些和其他原因使得这样的结构太复杂太过允许,而不是非常有益:您可以简单地做的是将专业化添加为friend,而不是以任何方式指示是否实例化此专业化或明确专门。

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

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