1

Suppose I've written class template declaration somewhere in collector.h:

template <class T, int maxElements>
class collector {

    T elements[maxElements];
    int activeCount;

public:

    collector();
    void process();
    void draw();

};

and implementing its three methods in collector.cpp:

template <class T, int maxElements> 
collector<T, maxElements>::collector(){
    //code here
}

template <class T, int maxElements>
void collector<T, maxElements>::process(){
    //code here
}

template <class T, int maxElements>
void collector<T, maxElements>::draw(){
    //code here
}

Is there any way of not writing template <class T, int maxElements> and <T, maxElements> for every function's implementation? Something like that:

template <class T, int maxElements>{

    collector<T, maxElements>::collector(){
        //code here
    }

    void collector<T, maxElements>::process(){
        //code here
    }

    void collector<T, maxElements>::draw(){
        //code here
    }

}
Fyodor
  • 2,793
  • 4
  • 21
  • 24
  • 1
    It's _not_ called "template class" because it isn't a class that happens to be a template. It's called a __class template__ because it's a template from which classes can be generated. – sbi Dec 09 '10 at 20:45

6 Answers6

5

Put the code inside the class definition in the header file.

[You'll probably wind up doing this anyway as soon as you try to build code that uses this class template. See here for background esp. the neglected answer from @Pavel Minaev.]

Community
  • 1
  • 1
Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
  • Thank you. But if my template class's using other classes extensively? – Fyodor Dec 09 '10 at 20:32
  • Then you have to fully specify the functions, just as you would with any other class. Template syntax just makes this a bit more wordy. This also makes building the full codebase more difficult, typically. There's nothing to prevent your header file from including the required dependencies, rather than your CPP file. – Steve Townsend Dec 09 '10 at 20:38
  • @furikeuretsu: The Standard allows for separating template classes into .h and .cpp, but due to the complications with implementation of that feature, there isn't a single compiler that actually allows it. If you really want to separate your class definition from the implementation, you can place the class definition at the top of the header, and the class implementation (what would be in your .cpp file) below it; however, most people just write their template classes inline. – Zac Howland Dec 09 '10 at 20:40
  • @Zac: See http://www.comeaucomputing.com/tryitout/, Comeau C++ implemented support for the `export` keyword. – Bill Dec 09 '10 at 20:44
  • @Bill: I should clarify: None of the common/major C++ compilers support it. And the export keyword is still rather controversial with the standards committee. – Zac Howland Dec 09 '10 at 20:46
  • 2
    @Zac: All compilers using EDG's frontend (for example Comeau, Intel) implement `export`. However, the very same people (of EDG) who opposed `export`, then were the only vendors to implement it, have later proposed to remove it from the standard. That proposal passed and `export` is officially deprecated in C++1x. – sbi Dec 09 '10 at 20:47
  • If, for example, inside of `draw()` function I use class `Dummy`, the only way I have is to declare `Dummy` before template class? – Fyodor Dec 09 '10 at 20:49
  • 1
    @furikuretsu: Yes, the declare before use rule applies to template code too. Although the compiler would probably not complain until you attempted to instantiate the template. – Clifford Dec 09 '10 at 20:59
  • 1
    @furikuretsu: You must include the definition for the class, yes. There are design patterns that could help you limit the impact that has on your code (e.g. create an abstract base class with the function `draw()` defined in it). – Zac Howland Dec 09 '10 at 21:01
  • 2
    The comment from @user193272 at the end of @Pavel Minaev's post is especially useful to know. – Clifford Dec 09 '10 at 21:04
  • 1
    @sbi: I believe they didn't just deprecate it, they removed it entirely (again, at EDG's suggestion). At least, that's what Herb Sutter said: http://herbsutter.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/ – jalf Dec 10 '10 at 08:52
  • @jalf: That could well be. I didn't follow this too closely. – sbi Dec 10 '10 at 08:56
1

Nope, you gotta write the template header every time.

eduffy
  • 39,140
  • 13
  • 95
  • 92
1

Typically, people implement template classes directly inline. They have to have their full source exposed to be used (unless you explicitly instantiate the lot, anyway) so there's little point doing otherwise.

Puppy
  • 144,682
  • 38
  • 256
  • 465
1

Is there any way of not writing template and for every function's implementation?

No, short of defining template members inline in the class template's definition, there is no way to do that.

sbi
  • 219,715
  • 46
  • 258
  • 445
1

The direct answer to your question has been answered by many above.

To know more on whats the best practice, refer to chapter 6 of C++ Templates - The complete guide book. It talks about which is the best place to declare and/or define template class, functions, member functions: in a .h/hpp or .cpp files.

yasouser
  • 5,113
  • 2
  • 27
  • 41
1
  1. There's always copy & paste!

  2. Unless you have a smart C++ template-aware linker closely coupled to your compiler, you'll have to put the code in-line in the header in any case and the problem goes away. You'll want to do that in any case if the code needs to be portable.

  3. If you really must then there is the somewhat perverse pre-processor macro solution:

    #define COLLECTOR_TEMPLATE template <class T, int maxElements>

  4. Explicitly instantiate for all the types you expect to need in the .cpp file so the compiler can generate the code a priori the linker will match the references templkates to the pre-instantiated definitions (see http://www.parashift.com/c++-faq-lite/templates.html#faq-35.13. You will however not be able to instantiate the template for new types.

For separate compilation of templates to work for arbitrarily instantiated classes, the compiler would have to embed the template source in the object file, then when the linker requires a particular instantiation to resolve a reference, it must then extract that source and pass it back to the compiler to generate the instantiated object code, which is then passed back to the linker. This requires the compiler and linker to work hand-in-glove, and for an object file format that supports template source embedding.

Most tool-chains do not support that, so you must either use in-line definition in the header, restrict use of the template to the same source file in which it is defined, or #include the .cpp containing the definition; all three of these are effectively the same thing - making the complete template definition visible to the compiler in a single compilation unit, but the first is the most conventional and flexible solution.

Clifford
  • 88,407
  • 13
  • 85
  • 165