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!)包含一个建议,以完全删除上面引用的句子,以及链接规则的一般合理化。
规范中的“can”是否表示源代码控制链接(例如通过命名空间{})或允许编译器选择实例化是具有内部链接还是外部链接?
这是控制链接的代码。从函数模板生成的函数具有外部链接,除非它是static函数模板或模板位于未命名的命名空间中 (C++11 起)。
换句话说,必须明确要求内部链接。