带模板的 C++ 共享库 : Undefined symbols error

标签 c++ templates gcc class linker

我正在尝试使用模板类链接到共享库,但它给了我“ undefined symbol ”错误。我已经将问题压缩到大约 20 行代码。

shared.h

template <class Type> class myclass {
  Type x;
public:
  myclass() { x=0; }
  void setx(Type y);
  Type  getx();
};

shared.cpp

#include "shared.h"
template <class Type> void myclass<Type>::setx(Type y) { x = y; }
template <class Type> Type myclass<Type>::getx() { return x; }

ma​​in.cpp

#include <iostream>
#include "shared.h"
using namespace std;

int main(int argc, char *argv[]) {
   myclass<int> m;
   cout << m.getx() << endl;
   m.setx(10);
   cout << m.getx() << endl;
   return 0;
}

这是我编译库的方式:

g++ -fPIC -c shared.cpp -o shared.o
g++ -dynamiclib -Wl,-dylib_install_name -Wl,libshared.dylib -o libshared.dylib shared.o

还有主程序:

g++ -c main.cpp
g++ -o main  main.o -L. -lshared

只得到以下错误:

Undefined symbols:
"myclass<int>::getx()", referenced from:
  _main in main.o
  _main in main.o
"myclass<int>::setx(int)", referenced from:
  _main in main.o

如果我删除 shared.h/cpp 中的"template"内容,并将它们替换为“int”,一切正常。另外,如果我只是将模板类代码复制并粘贴到 main.cpp 中,并且不链接到共享库,那么一切正常。

如何让这样的模板类通过共享库工作?

我正在使用带有 GCC 4.0.1 的 MacOS 10.5。

最佳答案

除了其他答案之外,您还可以显式实例化模板类。仅当您事先知道模板参数可能采用的类型时,这才有用。您使用库中的所有这些类型实例化模板。

要编译您的示例,只需将以下内容添加到 shared.cpp 的末尾:

// Instantiate myclass for the supported template type parameters
template class myclass<int>;
template class myclass<long>;

这将使用 Type=int 实例化模板并将实例化的代码放在共享库中。为您需要的所有类型添加尽可能多的显式实例化。

同样,如果您希望能够使用任意类型参数实例化模板,那么您必须将定义添加到头文件中,以便编译器知道模板的源代码在其他编译单元中实例化它时。

关于带模板的 C++ 共享库 : Undefined symbols error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1022623/

相关文章:

c++ - 为什么在函数体内使用 `typename`

c++ - 函数模板中出现无效的转换错误,其返回值取决于其泛型类型

gcc - 如何从静态库输出 (.a) 中删除所有绝对路径

c++ - WIN32 API C 程序 : Combo Box has an empty list or not dropping down despite populating with CB_ADDSTRING

c++ - 当我在 opencv 3.1.0 中包含 dnn 模块时出现链接错误

c++ - 位操作 : keeping the common part at the left of the last different bit

c++ - 以类似 cout 的符号在 C++ 中管理日志流

c++ - Derived对象调用Base方法的模板推导

linux - 交叉编译 glibc 导致构建错误

c++ - 定义成员函数时编译错误,但仅在 GCC 中