非成员函数模板什么时候有内部链接?

Jon*_*eld 4 c++ templates language-lawyer c++11

C++11 草案,14.0.4:

非成员函数模板可以有内部链接;任何其他模板名称应具有外部链接。

此查询是分离模板声明和定义的结果。例如,我们可以在头文件中写入以下内容。

template <typename T>
bool operator==(T const & l, T const & r);
Run Code Online (Sandbox Code Playgroud)

在注定要成为单个翻译单元的单个源文件中,我们编写定义。我们还在同一个翻译单元中为 type 隐式或显式实例化它foo

template <typename T>
bool operator==(T const & l, T const & r)
{
  return extract(l) == extract(r); // extract is uninteresting
}
Run Code Online (Sandbox Code Playgroud)

在第二个翻译单元中,它只能从头部看到定义,我们尝试使用foo{} == foo{},即调用在operator==别处实例化的 。

目前,这“有效”。链接器按照我的希望修补了两个翻译单元。

但是,如果功能模板具有内部链接,则链接可能会失败。例如,我们可以通过在匿名命名空间中实例化来强制执行此操作。

规范中的“can”是否表示源代码控制链接(例如 by namespace {})或允许编译器选择实例化是具有内部链接还是外部链接?

我不相信这里有任何未定义的行为,但我正在努力说服自己选择的链接不是实现细节。如果该符号已在至少一个 TU 中的上下文中实例化,表明它将是外部的,我是否可以依赖其他翻译单元可见的符号?

编辑:DR1603(感谢 Eugene Zavidovsky!)包含一个建议,以完全删除上面引用的句子,以及链接规则的一般合理化。

Max*_*kin 5

规范中的“can”是否表示源代码控制链接(例如通过命名空间{})或允许编译器选择实例化是具有内部链接还是外部链接?

这是控制链接的代码。从函数模板生成的函数具有外部链接,除非它是static函数模板或模板位于未命名的命名空间中 (C++11 起)。

换句话说,必须明确要求内部链接。