在 G++ 中未生成一些显式实例化
Some explicit instantiations not being generated in G++
我正在构建一个处理多种不同类型二进制 "languages" 的库,每种语言都有一个 "Processor" 类型。该库构建良好,到目前为止我已将问题缩小到以下模板代码:
// Processor.h
template <class A, class B = DefaultProcessor>
class Processor
{
public:
// Default constructor.
Processor(void);
// Constructor from DefaultProcessor pointer type.
Processor(B* pB);
virtual ~Processor(void){};
// Dereferencing operator
A* operator->(void) const;
private:
A* pRawPointer;
};
// Processor.cpp
template <class A, class B>
A* Processer<A, B>::operator->(void) const
{
if (nullptr == pRawPointer)
{
throw();
}
return pRawPointer;
}
// Constructor from DefaultProcessor pointer type.
template <class A, class B>
Processor<A, B>::Processor(B* pB)
: pRawPointer(dynamic_cast<A*>(pB))
{
}
我有几十种不同的 类 它支持,在我的库中,我有一长串显式实例化:
template class Processor<CustomType1>;
template class Processor<CustomType2>;
template class Processor<CustomType3>;
template class Processor<CustomType1, CustomType2>;
template class Processor<CustomType4>;
template class Processor<CustomType5>;
template class Processor<CustomType6>;
当我尝试构建链接到我的库的应用程序时,我在通过 g++ -Wall -std=c++11
编译时遇到以下错误,但在 Visual Studio 2015 中构建时没有任何问题:
undefined reference to `Processor<CustomType4, DefaultProcessor>::Processor(DefaultProcessor*)'
undefined reference to `Processor<CustomType4, DefaultProcessor>::operator->() const'
undefined reference to `Processor<CustomType5, DefaultProcessor>::Processor(DefaultProcessor*)'
undefined reference to `Processor<CustomType5, DefaultProcessor>::operator->() const'
在 Linux 中构建时,几乎就像没有完全生成显式实例化一样。我已经尝试通过以下方式在库中显式实例化:
template class Processor<CustomType4, DefaultProcessor>;
template class Processor<CustomType5, DefaultProcessor>;
这只会导致库由于重复的显式实例化而无法构建。
什么会导致此问题仅在 Linux 构建中出现?
谢谢。
您的模板未定义接受 DefaultProcessor *
作为参数的构造函数,因此显然未定义。
您的显式实例化必须存在于定义默认构造函数和 operator->
实现的同一文件中。否则,这些方法将不会被实例化。
我通过在定义模板的文件顶部定义一些虚拟 类 来测试您的代码。
struct DefaultProcessor { virtual ~DefaultProcessor() {} };
struct CustomType2 : DefaultProcessor {};
struct CustomType1 : CustomType2 {};
struct CustomType3 : DefaultProcessor {};
struct CustomType4 : DefaultProcessor {};
struct CustomType5 : DefaultProcessor {};
struct CustomType6 : DefaultProcessor {};
在包含模板方法定义的 C++ 文件底部,我添加了显式定义。然后我编译了这样的代码:
g++ -fPIC -std=c++0x -c t.cc
g++ -shared -o t.so t.o
为了观察实例化是否卡住,我使用了 nm
和 c++filt
。以下是包含 CustomType1
:
的符号
0000000000002a06 W Processor<CustomType1, CustomType2>::Processor(CustomType2*)
0000000000002a06 W Processor<CustomType1, CustomType2>::Processor(CustomType2*)
0000000000002a9c W Processor<CustomType1, CustomType2>::~Processor()
0000000000002a66 W Processor<CustomType1, CustomType2>::~Processor()
0000000000002a66 W Processor<CustomType1, CustomType2>::~Processor()
00000000000026dc W Processor<CustomType1, DefaultProcessor>::Processor(DefaultProcessor*)
00000000000026dc W Processor<CustomType1, DefaultProcessor>::Processor(DefaultProcessor*)
0000000000002772 W Processor<CustomType1, DefaultProcessor>::~Processor()
000000000000273c W Processor<CustomType1, DefaultProcessor>::~Processor()
000000000000273c W Processor<CustomType1, DefaultProcessor>::~Processor()
0000000000002ac2 W Processor<CustomType1, CustomType2>::operator->() const
0000000000002798 W Processor<CustomType1, DefaultProcessor>::operator->() const
我正在构建一个处理多种不同类型二进制 "languages" 的库,每种语言都有一个 "Processor" 类型。该库构建良好,到目前为止我已将问题缩小到以下模板代码:
// Processor.h
template <class A, class B = DefaultProcessor>
class Processor
{
public:
// Default constructor.
Processor(void);
// Constructor from DefaultProcessor pointer type.
Processor(B* pB);
virtual ~Processor(void){};
// Dereferencing operator
A* operator->(void) const;
private:
A* pRawPointer;
};
// Processor.cpp
template <class A, class B>
A* Processer<A, B>::operator->(void) const
{
if (nullptr == pRawPointer)
{
throw();
}
return pRawPointer;
}
// Constructor from DefaultProcessor pointer type.
template <class A, class B>
Processor<A, B>::Processor(B* pB)
: pRawPointer(dynamic_cast<A*>(pB))
{
}
我有几十种不同的 类 它支持,在我的库中,我有一长串显式实例化:
template class Processor<CustomType1>;
template class Processor<CustomType2>;
template class Processor<CustomType3>;
template class Processor<CustomType1, CustomType2>;
template class Processor<CustomType4>;
template class Processor<CustomType5>;
template class Processor<CustomType6>;
当我尝试构建链接到我的库的应用程序时,我在通过 g++ -Wall -std=c++11
编译时遇到以下错误,但在 Visual Studio 2015 中构建时没有任何问题:
undefined reference to `Processor<CustomType4, DefaultProcessor>::Processor(DefaultProcessor*)'
undefined reference to `Processor<CustomType4, DefaultProcessor>::operator->() const'
undefined reference to `Processor<CustomType5, DefaultProcessor>::Processor(DefaultProcessor*)'
undefined reference to `Processor<CustomType5, DefaultProcessor>::operator->() const'
在 Linux 中构建时,几乎就像没有完全生成显式实例化一样。我已经尝试通过以下方式在库中显式实例化:
template class Processor<CustomType4, DefaultProcessor>;
template class Processor<CustomType5, DefaultProcessor>;
这只会导致库由于重复的显式实例化而无法构建。
什么会导致此问题仅在 Linux 构建中出现?
谢谢。
您的模板未定义接受 DefaultProcessor *
作为参数的构造函数,因此显然未定义。
您的显式实例化必须存在于定义默认构造函数和 operator->
实现的同一文件中。否则,这些方法将不会被实例化。
我通过在定义模板的文件顶部定义一些虚拟 类 来测试您的代码。
struct DefaultProcessor { virtual ~DefaultProcessor() {} };
struct CustomType2 : DefaultProcessor {};
struct CustomType1 : CustomType2 {};
struct CustomType3 : DefaultProcessor {};
struct CustomType4 : DefaultProcessor {};
struct CustomType5 : DefaultProcessor {};
struct CustomType6 : DefaultProcessor {};
在包含模板方法定义的 C++ 文件底部,我添加了显式定义。然后我编译了这样的代码:
g++ -fPIC -std=c++0x -c t.cc
g++ -shared -o t.so t.o
为了观察实例化是否卡住,我使用了 nm
和 c++filt
。以下是包含 CustomType1
:
0000000000002a06 W Processor<CustomType1, CustomType2>::Processor(CustomType2*)
0000000000002a06 W Processor<CustomType1, CustomType2>::Processor(CustomType2*)
0000000000002a9c W Processor<CustomType1, CustomType2>::~Processor()
0000000000002a66 W Processor<CustomType1, CustomType2>::~Processor()
0000000000002a66 W Processor<CustomType1, CustomType2>::~Processor()
00000000000026dc W Processor<CustomType1, DefaultProcessor>::Processor(DefaultProcessor*)
00000000000026dc W Processor<CustomType1, DefaultProcessor>::Processor(DefaultProcessor*)
0000000000002772 W Processor<CustomType1, DefaultProcessor>::~Processor()
000000000000273c W Processor<CustomType1, DefaultProcessor>::~Processor()
000000000000273c W Processor<CustomType1, DefaultProcessor>::~Processor()
0000000000002ac2 W Processor<CustomType1, CustomType2>::operator->() const
0000000000002798 W Processor<CustomType1, DefaultProcessor>::operator->() const