开发者

Multiple-File Template Implementation

With normal functions, the declaration and definition are often separated across multiple files like so:

// Foo.h

namespace Foo
{
    void Bar();
}

.

// Foo.cpp

#include "Foo.h"

void Foo::Bar()
{
    cout << "Inside function." << endl;
}

It is my understanding that this cannot be done with templates. The declaration and definition must not be separate because the appropriate form of the template is created "on-deman开发者_开发问答d" when needed.

So, how and where are templates typically defined in a multiple-file project like this? My intuition is that it would be in Foo.cpp because that's where the "meat" of functions normally is, but on the other hand it's the header file that's going to be included.


You need to write definitions of templated methods in a .hxx file and include it at the end of your header file (.hh) in which you declare it. The .cc/.cpp is used to define non-templated methods.

So you'll have one .hh, one .hxx (included at the end of the .hh), and one .cc; so that including your templated class header file will include its definition too.

Example:

// list.hh
#IFNDEF LIST_HH
# DEFINE LIST_HH

template <typename T>
class List
{
  void fun1(T a);

  void fun2();
}

# include "list.hxx"

#ENDIF

// list.hxx
#IFNDEF LIST_HXX
# DEFINE LIST_HXX

# include "list.hh"

template <typename T>
void List::fun1(T a)
{
   // ...
}

#ENDIF

// list.cc

#include "list.hh"

void List::fun2()
{
   // ...
}


// anywhere.cc

#include "list.hh"

// ...

EDIT

There are several strategies to compile templates. The most common strategy is the one described above to let every user of the class template instantiate the code.

But, because the *.hh file includes the *.hxx file, each time a simple declaration of a template is needed, the full implementation comes with it. And if the implementation requires other declarations such as std::string, you force all the client code to parse the string header.

To avoid instantiations several times (time and space consuming), you can introduce a fourth type of file, *.hcc: files that must be compiled once for each concrete template parameter.

See Also Compile-Time Dependencies

EDIT2

Writing the template definition directly in the header file is called inclusion model. Doing so increases the cost of including the header. Not only because we added the definition of the template but because we included headers (, , whatever) which represent thousands of lines. A real problem for significant programs to compile (we are talking about hours of compilation here). The separation model

Source

And my last argument: keep clear the header file so that it only contains the class declaration and its documentation. Like that, any other programmer is able to fastly read your header file: what is the public interface of this class, what does the documentation says.


Template code stays in the .hh file. There's no reason to make them separate files, though it is good practice to put the definitions after all the declarations.

When the compiler generates template code, it flags it so that the linker knows that the instantiation of a template in one compilation unit (i.e. .o file) is the exact same code as one in another unit. It will keep one and discard the rest, rather than bailing out with a "multiply defined symbol" error.

This is true of modern compilers with good template support. In the case of GCC, since 2.8. (I know, I wrote a lot of code for gcc 2.7.2.2 before they smartened the linker up and you had to jump through hoops to make templates build right.)


I'm disappointed that no answers mentioned that the C++ standard permits you to separate the definition from the declaration. It goes like this:

// Foo.h
export template<class T> T f();

 

// Foo.cpp
#include "Foo.h"

export template<class T> T f()
{
    // blah blah
}

Unfortunately, almost no compilers support export. Comeau is one that does.

However, export is removed from C++ in C++0x.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜