在我正在开发的应用程序中,我有一个这样的模板函数:
template<class T>
void CIO::writeln(T item)
{
stringstream ss;
ss << item << '\r' << endl;
write(ss.str());
}
这个函数从几个地方调用,T = const char* 和 T=std::string。使用 CodeSourcery Lite 2008.03-41 (GCC 4.3.2) 编译并与 -O3 编译器标志链接良好。但是,由于我更改为 CodeSourcery Lite 2012.03-57 (GCC 4.6.3),使用 -O3 进行编译是可以的,但随后链接失败并显示undefined reference to void CIO::writeln<std::string>(std::string)
. 使用 -O2 或更低,一切正常,链接成功。
我对此进行了更深入的研究,并在汇编输出中发现了一些奇怪的东西:使用 -O2 编译时,我可以找到该函数的两个特化:一个用于 const char* ( _ZN3CIO7writelnIPKcEEvT_
),一个用于 std::string ( _ZN3CIO7writelnISsEEvT_
),但是使用 -O3 编译时,缺少第二个特化,这解释了链接错误。
这是编译器错误吗?这是一些奇怪的优化变成了邪恶的吗?
提前致谢!
编辑:此函数位于源文件中。根据 Mike Seymour 的评论,我将其移至标题,现在一切正常。我承认我应该早点意识到这一点。尽管如此,根据优化标志检查或不检查语言规则仍然让我感到害怕。