如果我编译以下代码:
//
// g++ static.cpp -o static.o
// ar rcs libstatic.a static.o
//
#include <iostream>
template < typename T >
struct TemplatedClass
{
void Test( T value )
{
std::cout << "Foobar was: " << value << std::endl;
}
};
template struct TemplatedClass < long >;
我得到一个静态库,如果我在该库上运行 nm,我会得到以下结果:
testcase% nm libstatic.a | c++filt | grep TemplatedClass
0000000000000207 s global constructors keyed to _ZN14TemplatedClassIlE4TestEl
0000000000000300 s global constructors keyed to _ZN14TemplatedClassIlE4TestEl.eh
0000000000000118 T TemplatedClass<long>::Test(long)
00000000000002a0 S __ZN14TemplatedClassIlE4TestEl.eh
但是,如果我编译以下代码,除了我添加了模板类的显式特化之外,它们是相同的......
//
// g++ static.cpp -o static.o
// ar rcs libstatic.a static.o
//
#include <iostream>
template < typename T >
struct TemplatedClass
{
void Test( T value )
{
std::cout << "Foobar was: " << value << std::endl;
}
};
template <>
struct TemplatedClass < long >
{
void Test( long value )
{
std::cout << "Value was: " << value << std::endl;
}
};
template struct TemplatedClass < long >;
... 并重新运行相同的命令:
testcase% nm libstatic.a | c++filt| grep TemplatedClass
testcase%
我没有得到匹配的符号。出于某种原因,编译器没有实例化模板,即使我明确要求它实例化也是如此。
谁能给我解释一下这是怎么回事?
最佳答案
您在类(模板)定义中有成员函数定义。这导致成员函数(模板)为 inline
.这对于模板类的成员函数来说并不重要,因为它的链接要求更多地取决于其实例化的性质。
但是在第二个例子中,成员函数void TemplatedClass<long>::Test(long)
不是函数模板,仍然是 inline
.因此,除非使用它,否则编译器不需要对它做任何事情,并且必须在使用它的所有文件中定义它。由于您声称这是在 static.cpp 文件中,内联函数可能不是您想要的。
我认为如果您将事情更改为:
template <>
struct TemplatedClass < long >
{
void Test( long value );
};
void TemplatedClass<long>::Test( long value )
{
std::cout << "Value was: " << value << std::endl;
}
当您定义显式特化时,您可能也不需要显式实例化(如果那是合法的话)。
关于c++ - 为什么我在静态库中缺少显式模板特化的符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3989435/