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

时间:2012-01-23 12:46:27

标签: c++ linux templates linker

我有一个奇怪的问题。在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,但这对我来说听起来不是一个理想的解决方案......

感谢您的帮助!

3 个答案:

答案 0 :(得分:9)

根据我的理解,您实际上是多次定义模板特化,这也会给Windows编译器带来错误。

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

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

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

相同的规则适用于您的模板专业化,与普通的非模板函数相同:使用inline或使用单独的声明和定义,通过添加

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

在标题中

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

.cpp文件中。

答案 1 :(得分:3)

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

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

这些功能之间的差别很小

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

void f(int x)
{ }

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

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

答案 2 :(得分:0)

我现在手头没有标准,但我认为必须宣布专业化inline