Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
219 views
in Technique[技术] by (71.8m points)

c++ - 为什么只能在头文件中实现模板?(Why can templates only be implemented in the header file?)

Quote from The C++ standard library: a tutorial and handbook :

(引用来自C ++标准库:教程和手册 :)

The only portable way of using templates at the moment is to implement them in header files by using inline functions.

(目前使用模板的唯一可移植方法是通过使用内联函数在头文件中实现它们。)

Why is this?

(为什么是这样?)

(Clarification: header files are not the only portable solution. But they are the most convenient portable solution.)

((澄清:头文件不是唯一的可移植解决方案。但是它们是最方便的可移植解决方案。))

  ask by MainID translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It is not necessary to put the implementation in the header file, see the alternative solution at the end of this answer.

(这是没有必要把落实在头文件中,看到这个答案的末尾替代解决方案。)

Anyway, the reason your code is failing is that, when instantiating a template, the compiler creates a new class with the given template argument.

(无论如何,您的代码失败的原因是,在实例化模板时,编译器会使用给定的template参数创建一个新类。)

For example:

(例如:)

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

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

When reading this line, the compiler will create a new class (let's call it FooInt ), which is equivalent to the following:

(阅读此行时,编译器将创建一个新类(我们将其FooInt ),其等效于以下内容:)

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

Consequently, the compiler needs to have access to the implementation of the methods, to instantiate them with the template argument (in this case int ).

(因此,编译器需要访问方法的实现,以使用模板参数(在本例中为int )实例化它们。)

If these implementations were not in the header, they wouldn't be accessible, and therefore the compiler wouldn't be able to instantiate the template.

(如果这些实现不在头文件中,则将无法访问它们,因此编译器将无法实例化模板。)

A common solution to this is to write the template declaration in a header file, then implement the class in an implementation file (for example .tpp), and include this implementation file at the end of the header.

(常见的解决方案是将模板声明写在头文件中,然后在实现文件(例如.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
}

This way, implementation is still separated from declaration, but is accessible to the compiler.

(这样,实现仍与声明分开,但编译器可以访问。)

Alternative solution (替代解决方案)

Another solution is to keep the implementation separated, and explicitly instantiate all the template instances you'll need:

(另一个解决方案是使实现分离,并显式实例化所需的所有模板实例:)

// 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

If my explanation isn't clear enough, you can have a look at the C++ Super-FAQ on this subject .

(如果我的解释不够清楚,您可以阅读有关此主题C ++ Super-FAQ 。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...