views:

34

answers:

2

I have a class with several template member functions that I would like to distribute among several source files to speed up compilation times. (The templates are implementation details and are not intended to be used outside the class, hence their definition in sources not headers.)

How would I go about splitting up these templates in such a way that I will not get linker errors? If I have source file A using a template defined in source file B, how do I make sure the appropriate instance of the template is constructed by the compiler?

+3  A: 

I could not answer it better than C++ FAQ lite:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.15

dark_charlie
@dark: `export` is implemented by almost no compilers, and is being deprecated in C++0x. It should not be used for new code.
Billy ONeal
Ah, sorry, I meant to link to 35.15. However, it's anyways good to read all the FAQs starting with 35.13 for a better understanding.
dark_charlie
@Billy: `export` is *not* being deprecated in C++0x -- it's being removed completely. Since only one compiler front-end (EDG) implemented it, and the EDG guys asked for it to be removed, there didn't seem to be much reason to delay removing it.
Jerry Coffin
@Jerry: Thanks. I stand corrected :)
Billy ONeal
A: 

Simply don't declare those template items as part of the class in the header file. Then, define your templates only in the source file. For example:

MyClass.hpp

class MyClass
{
public:
    void SomePublicMethod() const;
};

MyClass.cpp

template<class T>
void SomethingWithT(T myVal)
{
    // ...
}

void MyClass::SomePublicMethod() const
{
    SomethingWithT(42);
}
Billy ONeal
Nice workaround :) It might not look so elegant though as it requires moving member methods (even though they are private) outside the class and then passing the `this` pointer. Manual template instantiation is a cleaner approach in my opinion.
dark_charlie
@Billy: What if I want `SomethingWithT` in source file A and `SomePublicMethod` in source file B? (`SomethingWithT` takes a _long_ time to compile...)
fbrereto
@dark: Except no known compiler **implements** manual template instantiation. Yes, I agree that would be cleaner, but it relies on the `export` keyword which is A. only implemented by EDG, and B. being removed.
Billy ONeal
@fbereto: You can't do that. To do that would require `export`, which runs into the problems in my previous comment. Templates are instantiated where they are used.
Billy ONeal
Manual template instantiation is (of course) implemented in all compilers that support templates. Have you read (the updated link to) the FAQ I posted in my answer?
dark_charlie
@dark_charlie: Yes, I did read the link. Yes, you can force the compiler to instantiate a template in a translation unit. But you **cannot** force the compiler to **not** instantiate the template where it is used in another translation unit.
Billy ONeal
@Billy ONeal: Sorry, I don't understand your comment :( Of course, once a template is instantiated, it cannot be "uninstantiated".
dark_charlie