Re: Why "already defined in"?
"Joachim" <Joachim@discussions.microsoft.com> wrote in message
news:7D152568-033E-4C2F-BD96-E877910A453A@microsoft.com
Thanks John,
How do I do with template functions then? Wouldn't they have the same
problem if you put them in the .h file?
A template isn't really a function. It is, as the name suggests, a template
that the compiler uses to create functions. Thus putting them in header
files doesn't cause a problem.
Templates are instantiated by the compiler, not the linker, which means that
templates have to be visible within the translation unit that uses them.
Thus if you want to use a template in more than one translation unit, then
(subject to a few possible workarounds) you have to define it in a header
file. If you define it in a .cpp file, then other translation units can't
see it (subject to the aforementioned workarounds).
Note that the foregoing does not apply to specializations of templates. Thus
template <class T>
void foo(const T &t)
{
std::cout << t << std::endl;
}
can and generally should go in the header file, but
template<>
void foo<int>(const int &t)
{
printf("%d\n", t);
}
should go in a .cpp file. The specialization is a "real" function, so the
normal non-template rules apply to it.
The specialization is actually rather tricky. For example, if you
1. put the general template in the header file one.h,
2. put the specialization in the implementation file one.cpp
3. include one.h in both one.cpp and a second file, two.cpp, and call the
function in two.cpp with an integer parameter
then you will still get a multiple definitions error. The reason is as
follows.
The compiler generates the specialization in the translation unit for
one.cpp, as expected. However, it also generates an instantiation of the
function in the translation unit for two.cpp, based on the general template
in the header file. The linker then finds two function definitions. To avoid
this, you need to add a *declaration* of the specialization to the header
file:
template<>
void foo<int>(const int &t);
This will tell the compiler not to create an int version of the function
based on the general template because a specialization is defined somewhere.
In other words, since the specialisation is a "real" function, you should
treat it the same way you would a "real" function, with a declaration in the
header file and an implementation in the .cpp file.
--
John Carson