将C ++模板函数定义存储在.CPP文件中

时间:2020-03-06 14:32:51  来源:igfitidea点击:

我有一些模板代码,我希望将其存储在CPP文件中,而不是内联在标头中。我知道只要我们知道将使用哪种模板类型,就可以完成此操作。例如:

.h文件

class foo
{
public:
    template <typename T>
    void do(const T& t);
};

.cpp文件

template <typename T>
void foo::do(const T& t)
{
    // Do something with t
}

template void foo::do<int>(const int&);
template void foo::do<std::string>(const std::string&);

请注意,foo :: do模板函数的最后两行仅与ints和std :: strings一起使用,因此这些定义意味着应用程序将链接。

我的问题是这是一个讨厌的黑客,还是可以与其他编译器/链接器一起使用?目前,我仅在VS2008中使用此代码,但希望将其移植到其他环境。

解决方案

是的,这是进行专门化显式实例化的标准方法。如我们所述,我们无法使用其他类型实例化此模板。

编辑:根据评论更正。

我们可以通过在标题中定义模板或者通过上述方法来解决我们描述的问题。

我建议从C ++ FAQ Lite中阅读以下几点:

  • 为什么不能将模板类的定义与其声明分开,然后将其放入.cpp文件中?
  • 如何避免模板函数出现链接器错误?
  • C ++关键字导出如何帮助解决模板链接器错误?

他们详细介绍了这些(和其他)模板问题。

在支持模板的任何地方都可以正常工作。显式模板实例化是C ++标准的一部分。

在最新标准中,有一个关键字(export)可以帮助缓解此问题,但除Comeau之外,没有在我知道的任何编译器中实现。

有关此问题,请参见FAQ-lite。

这段代码格式正确。我们只需要注意,模板的定义在实例化时可见。引用标准14.7.2.4:

The definition of a non-exported function template, a non-exported member function template, or a non-exported member function or static data member of a class template shall be present in every translation unit in which it is explicitly instantiated.

我们所举的例子没有错。但我必须说,我认为将函数定义存储在cpp文件中并不高效。我只了解需要将函数的声明和定义分开。

当与显式类实例一起使用时,Boost Concept Check Library(BCCL)可以在cpp文件中生成模板功能代码。