为什么优化标志会导致某些模板函数出现链接器错误?

时间:2011-07-26 10:22:33

标签: c++ templates linker

我遇到一个问题,即应用程序在调试模式下编译正常,并关闭所有优化。 但是,当我编译发布时,它会打印出未解决的链接错误。

有问题的功能如下:

template <typename T>
T & Block::val(size_t offset) 
{
    return *(reinterpret_cast<T*>(_data + offset)); 
}

template <typename T>
const T & Block::val(size_t offset) const 
{ 
    return *(reinterpret_cast<T*>(_data + offset)); 
}

我得到的错误看起来像是:

undefined reference to `unsigned long long& Block::val<unsigned long long>(unsigned long)'

可能导致这种情况的原因是什么?

2 个答案:

答案 0 :(得分:3)

您通常不会将模板实现放在.cpp中,而是将.h或.inl放在.h中,可能是.o的调试版本更加自由,它导出的符号

在调试和发布.o版本上运行nm并对符号进行区分。

由于One Definition Rule,模板在链接器中不常见。对于模板,正文位于标题中,这会产生多个等效的定义,每个翻译单元一个。链接器允许它们一直到最后一刻,在那里它任意选择一个并丢弃其他的。

我在这里猜测,但我怀疑当你没有优化编译时,正文被视为正常,但是当进行优化时,编译器会花费一些额外的努力来确定这个正文在其他翻译中不可见单位并拒绝将其导出。

查找extern templates

答案 1 :(得分:2)

  

奇怪,将它们从源文件移动到头文件中   编译好。

这丝毫不奇怪。功能模板定义从第一天开始就属于头文件。不要把它们放在源头。如果这样做,编译器将无法在实例化时看到它们。