tags:

views:

5151

answers:

7

I have some template code that I would prefer to have stored in a CPP file instead of inline in the header. I know this can be done as long as you know which template types will be used. For example:

.h file

class foo
{
public:
    template <typename T>
    void do(const T& t);
};

.cpp file

template <typename T>
void foo::do(const T& t)
{
    // Do something with t
}

template void foo::do<int>(const int&);
template void foo::do<std::string>(const std::string&);

Note the last two lines - the foo::do template function is only used with ints and std::strings, so those definitions mean the app will link.

My question is - is this a nasty hack or will this work with other compilers/linkers? I am only using this code with VS2008 at the moment but will be wanting to port to other environments.

A: 

Yes, that's the standard way to do specializiation explicit instantiation. As you stated, you cannot instantiate this template with other types.

Edit: corrected based on comment.

Lou Franco
Being picky about terminology it's an "explicit instantiation".
Richard Corden
+13  A: 

The problem you describe can be solved by defining the template in the header, or via the approach you describe above. I recommend reading points 35.12, 35.13, and 35.14 from the C++ FAQ Lite:

http://www.parashift.com/c++-faq-lite/templates.html

They go into a lot of detail about these (and other) template issues.

Aaron N. Tubbs
+1  A: 

This should work fine everywhere templates are supported. Explicit template instantiation is part of the C++ standard.

moonshadow
C has templates? Wow. ;-)
Konrad Rudolph
Same comment... :-)
paercebal
Duh. Fixed. Other people are quoting exact paragraphs so my answer adds nothing anyway :)
moonshadow
+2  A: 

There is, in the latest standard, a keyword (export) that would help alleviate this issue, but it isn't implemented in any compiler that I'm aware of, other than Comeau.

See the FAQ-lite about this.

Ben Collins
Herb Sutter has argued (currently unsuccessfully) to have export removed from the language. But I don;t think the fight is over yet.
Martin York
AFAIK, export is dead because they are facing newer and newer issues, each time they resolve the last, making the overall solution more and more complicated. And the "export" keyword won't enable you to "export" from a CPP anyway (still from H. Sutter's anyway). So I say: Don't hold your breath...
paercebal
+1  A: 

This code is well-formed. You only have to pay attention that the definition of the template is visible at the point of instantiation. To quote the standard, § 14.7.2.4:

The definition of a non-exported function template, a non-exported member function template, or a non-exported member function or static data member of a class template shall be present in every translation unit in which it is explicitly instantiated.

Konrad Rudolph
A: 

There is nothing wrong with the example you have given. But i must say i believe it's not efficient to store function definitions in a cpp file. I only understand the need to separate the function's declaration and definition.

When used together with explicit class instantiation, the Boost Concept Check Library (BCCL) can help you generate template function code in cpp files.

Benoît
A: 

Just a nit-pick but you should put the explicit instantiation in the header file not the source file. Putting it in the source file gives you nothing since whatever code can see the template instantiation can also see the definition, the whole point of explicit instantiation is to tell the compiler that the following functions will be defined and the linker will find them later on.

<nit-pick>

Motti