我正在尝试将模板函数的定义移出头文件。
我知道,为了做到这一点,我可以使用我想从外部看到的所有类型(在链接期间)显式实例化此函数。但是,在源文件中(连同函数的定义一起),我具有所有必要类型的函数用法(隐式实例化)。该代码可以正常工作并与-O0完美链接,但无法与-O2链接。
我能够使问题最小化:
// a.cpp
#include "b.h"
int main() {
bar<int>();
return 0;
}
// b.h
template <class T> void bar();
// b.cpp
#include "b.h"
template <class T> void bar() {}
void foo() { bar<int>(); }
如果我用-O0和-O2编译 b.cpp ,我将在目标文件中得到一组不同的符号:
> clang++ -c b.cpp -o b.o && nm -A b.o
b.o:0000000000000000 W _Z3barIiEvv
b.o:0000000000000000 T _Z3foov
> clang++ -c b.cpp -O2 -o b.o && nm -A b.o
b.o:0000000000000000 T _Z3foov
gcc 也是如此。
看起来编译器内联了实例化函数并删除了它,因为他们看不到该函数的任何其他用法。
是否可以在不显式实例化隐式实例化模板函数的情况下将其删除?
谢谢!
UPD :这个相关问题的answer(如@ Jarod42所指出的)也回答了我的问题:根据标准,没有显式实例化就不可能做到这一点
答案 0 :(得分:-1)
根据我从代码片段中得到的信息,您缺少模板功能的实际定义。您正在做的就是调用它。
您只需要定义模板功能。可能看起来像这样(根据您的情况,很可能位于b.cpp
中
tempate <class T>
void bar()
{
// My function
std::cout << "bar()" << std::endl;
}