Linux C++:如何在多个文件中正确使用模板专用化

Linux C++: How to properly use template specializations across multiple files?

本文关键字:专用 文件 C++ Linux      更新时间:2023-10-16

我有一个奇怪的问题。在Windows上,使用Visual Studio 2010以及"英特尔编译器",一切都会按预期进行链接。但是,当我尝试在Linux上使用CLang 3.0编译代码时,它确实会编译(如果我只使用一个CPP文件,它也会链接和运行),但不会链接。

消息是有多个符号定义,指的是模板实例。例如,考虑在多个编译单元之间共享的头文件中的以下两行:

 template<class T> void myFunc(T in) { }
 template<> void myFunc<int>(int in) { }

现在,从Linux链接器中,我可以得到如下内容:

"file xyz":"myFunc(int-in)"的多个定义,首次在"some file"中定义。

但我该如何防止这种情况发生呢?既然它在Windows上运行,我想它也应该在Linux上运行?

静态模板数据成员也是如此,它们或多或少与上面相同,只是您声明了一个变量而不是一个函数。我更希望它适用于静态模板数据成员。

如果其他一切都失败了,我想我仍然可以创建一个"MakeAll.cpp"文件,其中只包括所有的cpp,但这对我来说不是一个理想的解决方案…

谢谢你的帮助!

据我所知,实际上您已经多次定义模板专业化,这也会给Windows编译器带来错误。

在您的头文件中,您通过提供正文来定义函数:

template<> void myFunc<int>(int in) { }

此定义将存在于多个编译单元中,并且链接器应该抱怨。

与普通的非模板函数一样,同样的规则也适用于模板专用化:要么使用inline,要么使用单独的声明和定义,通过放置

template<> void myFunc<int>(int in);

在标头和中

template<> void myFunc<int>(int in)
{
    // ...
}

在CCD_ 2文件中。

模板由编译器实例化,编译器有责任确保它们只定义一次。

当你完全专门化一个函数时,它不再是一个模板(而是一个普通的函数),你有责任确保它不是多重定义的。

的这些功能之间几乎没有区别

template<>
void f<int>(int x)
{ }
void f(int x)
{ }

当涉及到一个定义规则时。

添加inline在这两种情况下都有帮助。

我现在手头没有标准,但我认为必须将专业化声明为inline