为什么C++模板只能在头文件中实现?

目前使用模板的唯一可移植方法是使用内联函数在头文件中实现它们。头文件不是唯一的可移植解决方案。 但它们是最方便的可移植解决方案。


 
c++
templates
c++-faq
2s

推荐解答

没有必要将实现放在头文件中,请参阅本答案末尾的替代解决方案。 无论如何,代码失败的原因是,在实例化模板时,编译器会创建一个具有给定模板参数的新类。 例如:

template<typename T>
struct Foo
{
    T bar;
    void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo<int> f;

读取此行时,编译器将创建一个新类(让我们称之为FooInt),这相当于以下内容:

struct FooInt
{
    int bar;
    void doSomething(int param) {/* do stuff using int */}
}

因此,编译器需要访问方法的实现,以使用template参数(在本例中为int)实例化它们。 如果这些实现不在标头中,则它们将不可访问,因此编译器将无法实例化模板。 一个常见的解决方案是在头文件中编写模板声明,然后在实现文件(例如.tpp)中实现该类,并在头的末尾包含此实现文件。

// Foo.h
template <typename T>
struct Foo
{
    void doSomething(T param);
};

#include "Foo.tpp"

// Foo.tpp
template <typename T>
void Foo<T>::doSomething(T param)
{
    //implementation
}

这样,实现仍然与声明分离,但编译器可以访问。 另一种解决方案是保持实现分离,并显式实例化您需要的所有模板实例:

// Foo.h

// no implementation
template <typename T> struct Foo { ... };

//----------------------------------------    
// Foo.cpp

// implementation of Foo's methods

// explicit instantiations
template class Foo<int>;
template class Foo<float>;
// You will only be able to use Foo with int or float

如果我的解释不够清楚,你可以看一下关于这个主题的C ++ Super-FAQ。

  nopapp推荐


其它解答 (1)

C++模板的定义是否只能放在头文件中? - imred的专栏 - CSDN博客
C++模板的定义是否只能放在头文件中?-imred的专栏-CSDN博客原C++模板的定义是否只能放在头文件中?2018年05月10日00:09:53imred阅读数:182版权声明:转载请注明来源:https://blog.csdn.net/imred/article/details/80261632C++模板的定义是否只能放在头文件中?答案是否定的,你也可以放在.cpp源文件中。不过,你最好还是放在头文件中,下面我会解释为什么。我不了解编译器的实现细节,无法从原理上进行解释,但可以从行为上进行探究,此处使用的编译器为gcc5.4.0。情况1就以一个最简单的加法函数的模板为例,一般我们会把定义
  csdn.net