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.
精彩评论