使用外部模板时链接器错误
Linker error when using an extern template
我有一个模板的工作代码。与stl::string类似,我主要是在多个编译单元中使用带有一个参数的模板。为了节省时间,我试图使用外部实例化。然而,像下面这样更改行会产生一个错误。正确的做法是什么?(注:使用c++0x标志在gcc上编译)
typedef myTemplate_base<commonType> myTemplate;
extern template class myTemplate_base<commonType>; //using "extern template myTemplate" wont work
我在项目中添加了一个额外的cpp文件,其中包含以下内容。
template class myTemplate_base<commonType>;
链接器出现这个错误消息(给出主文件中第一个对象实例化(myTemplate someVar;
)的行作为错误源):
未定义引用'myTemplate_base::~myTemplate_base()'
然而,该类型在类中具有以下定义~myTemplate() = default;
编辑:如果你有一个更好的标题,请评论,让合适的人看看这个
Edit2:有一个有趣的事情,template class myTemplate_base<commonType>
的添加极大地增加了可执行文件的大小(在450k二进制文件上+100k),即使模板在主程序中使用(为了编译,我必须将extern
部分注释出来)。这暗示链接器保持了具有相同实例化的模板的两个实现/me忽略了一些东西。
您发现了一个编译器错误。我用g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
复制了它。解决方法是将析构函数保留为隐式默认值。只有当析构函数显式地将其标记为默认(= default
)时,才会出现链接器错误。
= default
会使编译器混淆,认为析构函数将在其他地方定义。
代码膨胀是由外部模板引起的。编译器只实例化模板类中实际使用的方法。这通常比定义的数字少得多。当你使用extern template
强制实例化一个类时,编译器会发出所有方法的代码(除了刚才发现的析构函数)。
g++ -c -std=c++0x main.cpp
g++ -c -std=c++0x extern.cpp
g++ main.o extern.o
header.hpp
#pragma once
#include <iostream>
#include <string>
#include <typeinfo>
template< typename T >
class Foo
{
public:
Foo( void ) :
m_name( typeid(T).name() ),
m_t( T() )
{ }
// add or remove this to cause the error
~Foo( void ) = default;
void printer( void )
{
std::cout << m_name << std::endl;
}
T returner( void )
{
return m_t;;
}
private:
std::string m_name;
T m_t;
};
extern template class Foo<int>;
extern.cpp
#include "header.hpp"
template class Foo<int>;
main.cpp
#include "header.hpp"
int main()
{
Foo<int> fi;
fi.printer();
Foo<float> ff;
ff.printer();
}
- 静态数据成员的问题-修复链接错误会导致编译器错误
- Visual Studio mkl_link_tool.exe链接错误
- C++ 实现模板单例类时出现链接错误
- 使用类模板的方法链接错误
- MySQL C++连接器链接错误
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- 运行 C++ 单元测试时LNK2005链接错误
- 对 CMake 中'cudaRegisterLinkedBinary'链接错误的未定义引用?
- 链接错误,包括我创建的相同头文件 - C++
- 在Embarcadero C++ Builder中生成的DLL未解决的外部链接错误
- 使用标头保护的多个定义链接错误
- 链接错误:未定义对 stdscr 和 wgetch 的引用
- 使用 Vivek 的 Vcam / 捕获源过滤器构建/链接错误
- 升压program_options中的链接错误
- 使用 g++ 预处理器进行替换会导致链接错误
- 在调试配置中编译工作正常,但发布会给出链接错误
- 相邻矩阵设置链接错误
- 包含常量变量并包含在多个文件中的标头的链接错误
- C++链接错误,我理解但无法解决
- 是什么导致macOS Mojave上的GoogleTest链接错误