2

Any one of my C++ projects will generate a linker error unless I include an explicit template instantiation for every templated class/method/function I author and use.

STL classes seem to have no such problem.

Is there some simple code of conduct (pun intended) I can adhere to which allows deferred instantiation like that of STL?

Thanks for listening.

KomodoDave
  • 7,239
  • 10
  • 60
  • 92
  • 3
    You will have to provide some example code. – Šimon Tóth Sep 30 '11 at 19:02
  • 1
    Are you putting the definitions of your template classes in a header file? If not, see for example: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12 – DeCaf Sep 30 '11 at 19:02
  • possible duplicate of [Why should the implementation and the declaration of a template class be in the same header file?](http://stackoverflow.com/questions/3749099/why-should-the-implementation-and-the-declaration-of-a-template-class-be-in-the-s) – Mark B Sep 30 '11 at 19:03
  • I think the explanation you are looking for is here: http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – minus Sep 30 '11 at 19:05

3 Answers3

8

For templates you need to put all the template code and methods into headers rather than source files. The standard library does this.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • Thanks to Mark and all others for your informative answers. I'll be sure to implement templated definitions in the header from now on! – KomodoDave Sep 30 '11 at 19:35
  • or, simply have the header include the cpp file, for the same effect. (Make sure the header has an include guard of some sort) – Mooing Duck Sep 30 '11 at 20:00
  • @Mooing Duck: well, if you've already written the `.cpp` file, and your source control for some bizarre reason makes it difficult to rename a file, I suppose you *could* do that. Similarly, when rewriting code from Java to C++, you *could* leave the filename as `.java`. Most people don't, though. – Steve Jessop Sep 30 '11 at 22:57
  • @SteveJessop: I always appreciate when declaration is separate from implementation. That's _why_ we have `.hpp` and `.cpp` to begin with. – Mooing Duck Oct 01 '11 at 16:34
  • @Mooing Duck: OK, but whether it contains declarations or definitions, `.cpp` isn't the usual extension for a file that's going to be included into multiple TUs in the same program. – Steve Jessop Oct 04 '11 at 10:12
1

You should put most parts of a template within the header file. This applies equally to template classes as well as template functions within normal classes.

The exception that you should know to this rule is that when you specialize a template, you need to put the specialization in the implementation/.cpp file because a specialization is a concrete type. The actual template definitions on the other hand will need to be run through multiple times, one for each template parameter type used with the template - so they must go in the header file (they're not concrete type-wise).

e.g. put:

template typename<T> foo(T val) { std::cerr << "DEFAULT"; }

in the header file and its specialization for an int:

template<> foo<int>(int val) { std::cerr << "INT"; }

in the cpp file because the int version is a concrete, fully defined function whereas the T version is a template definition which will be used many time to generate many concrete functions.

John Humphreys
  • 37,047
  • 37
  • 155
  • 255
  • Do you "need" to put specializations into an implementation file, or are you *allowed* to? Seems like the specialization would be similar to an inline function. – Mark Ransom Sep 30 '11 at 19:40
  • I believe you need to, but I suspect inlining the specialization would make it work in the header file to counteract that need. If you left it in the header file un-inlined you would most certainly get a multiple-definition error on that int specialization though. – John Humphreys Sep 30 '11 at 19:56
  • It's true, a function specialization needs to be `inline` if you're defining it in multiple TUs. For classes it's different, since a class is allowed to be defined in multiple TUs. Note that if you put the non-inline specialization in one TU, then you need to declare it in any others that use it, otherwise they'll instantiate the general template and you get multiple definitions. – Steve Jessop Sep 30 '11 at 23:18
1

Most of the time a template class is defined completely in the header file. This allows the compiler to generate the body of code on the fly if it hasn't already come across the combination of function and template parameters that you're using.

You can still use a template with separate header and implementation files, but it's much less convenient. As you've discovered, you must anticipate each template parameter and put that combination in the implementation file, so that the compiler can generate the necessary code.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622