链接显式类模板实例化
Linkage of explicit class template instantiation
在不同的编译单元中允许同一类模板具有相同类型的多个实例化吗?函数模板呢?
示例代码如下:
test.hpp
template <typename T>
class A
{
public:
T out();
};
template <typename T>
T A<T>::out()
{
return T(1);
}
test1.cpp
#include "test.hpp"
template class A<int>;
int testFn()
{
return A<int>().out();
}
test2.cpp
#include "test.hpp"
template class A<int>;
extern int testFn();
int main()
{
return testFn() == A<int>().out();
}
如果我运行
g++ -std=c++11 test1.cpp test2.cpp -o test
它编译时不会抱怨重复的定义。
我指的是标准[1][2]的旧草案,并假设链接部分没有太大变化(除了匿名命名空间)。类模板通过3.5p4和14p4具有外部链接。如果是这样的话,我认为c++应该抱怨A::out()的重复定义。我遗漏了什么吗?
如果test.hpp定义了一个没有"static"或"inline"的函数模板怎么办?
谢谢。
[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf[2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
在实现中找到这些问题的答案的一个好方法是使用"nm "。通常,如果你将nm的输出管道到c++filt中,混乱的c++符号会更容易读懂。
例如,如果你用"-c"来编译"。每个编译单元的0 ' s,然后可以运行nm。当我这样做时,我看到模板成员是弱符号"W"代码(在x86 linux上)。这意味着可以使用多个定义,并且以某种特定于系统的方式。如果我创建一个非模板化的函数,它将在对应的目标文件的两个翻译单元中显示为"T"。这将导致多个定义的符号。
通常c++模板是根据需要实例化的(没有完整的实例化),这将允许你在声明头之外使用_impl类型头。
实际上不允许将成员模板定义为静态(这会产生错误)。您可以将其定义为内联。在这种情况下,您将看不到使用nm的成员模板的任何符号,因为它已被内联。
- 链接提升 - 未定义对"提升::序列化::singleton_module::get_lock()"的引用
- C++ 为什么在定义的编译和链接之前引用外部实例的程序
- 可视化工作室项目中C++预编译标头未正确链接
- 带有预处理器的可视化C++条件链接
- JNI 不满意链接错误: 动态链接库 (DLL) 初始化例程失败
- C :(不重复)积分静态成员初始化(不仅是声明!),导致链接器错误,原因
- 链接器如何处理跨翻译单元的相同模板实例化
- 模板链接器错误的显式实例化
- 类模板的成员函数模板找不到定义,尽管存在显式实例化。不链接
- 静态成员初始化链接错误
- 非实例化模板成员的编译时错误,而不是链接时错误
- 调用实例化函数时发生链接器错误
- 从文件描述符实例化套接字对象的非侵入性方法
- 实例化模板类时出现链接器错误
- 打印实例化链
- 为什么为模板实例化声明运行时多态性会导致链接器错误
- 当我把模板放在另一个要实例化的类中时,模板链接错误
- 使用LLVM-Clang隐式实例化私有c++模板时的链接器错误
- c++模板特化链接器错误
- 链接显式类模板实例化