views:

92

answers:

6

What is the best pratice in regards to defining a template in C++?

template <class T>
class A
{
private:
    // stuff
public:
    T DoMagic()
    {
        //method body
    }
}

Or:

template <class T>
class A
{
private:
    // stuff
public:
    T DoMagic();
}

template <class T>
A::T DoMagic()
{
    // magic
}

Another way? I seem to stumble over some controversy regarding this subject. So; What path to choose?

+3  A: 

This is completely a matter of style. That said however:

  1. choose a way and stick to it -- either all inline, or all out, or mixed based on some rule
  2. personally I use a 3 line rule. If the method body in the template is longer than 3 lines I move it outside.

There's no real reason not to include all definitions inline (they are inline from the compilers POV anyway), however, many people argue that keeping them separate is more clean, and allows the class definition to be more readable.

Kornel Kisielewicz
Alright, so there is, as I would expect, no difference in performance? Since I'm used to C# class definitions and you can't use header files I might as well keep the definition inline I guess.
Oxymoron
@Oxymoron: Template code would be necessarily inline anyway (that is, the compiler has the choice whether to inline or not), since you can't implement them in a separate compilation unit.
UncleBens
@Oxymoron: you can compile and compare the binaries -- there should be no difference between your examples.
Kornel Kisielewicz
A: 

For a one-off instance like your example, it makes little difference.

What happens when there are lots of templates with lots of variations? It then helps to put similar types of apples together, and similar types of oranges together away from them. Of course, this must all be done as intuitively as practical. That is greatly affected by the culture of programmers working with the code.

wallyk
+1  A: 

This is a religious (style) issue. I prefer to define my functions outside of the template declaration for classes that have more than one method or the few methods are simple.

In either case, my understanding is that the template declaration and the method definitions must be in the same translation unit. This is because the template is more like a stencil, the compiler plugs a given type into the stencil and generates code for the given type.

Whatever you decide, just be consistent.

Thomas Matthews
+1  A: 

I usually define all the methods outside but each time I wish C++ had some sort of "template blocks":

template <class T>
struct A
{
     T foo();
     T bar(T * t);
     T baz(T const & t);
};

template <class T>  // Made-up syntax
{
    T A::foo()
    {
        //...
    }

    T A::bar(T * t)
    {
        //...        
    }

    T A::baz(T const & t)
    {
        //...
    }
}
Manuel
+1  A: 

If the functions are non-trivial (i.e. more than one or two lines), consider defining them separately. This makes the interface of the class much easier to navigate, read and understand for the users of your class, who most likely shouldn't have to look at the actual implementation of each method.

Frederik Slijkerman
+1  A: 

Use an increasing level of seperation as the templates you write grow larger and more complex. Performance will be the same no matter how you seperate the definitions from the declarations, so your main concern here should be readability and maintainability.

When writing a simple template used only in one place, declare and define it inline with the declarations right in the CPP file where you're going to use it. There's no reason to force a global recompile if only one block of code needs this template.

file.cpp

template<class Gizmo> bool DoSomethingFancy()
{
 // ...
}

For small template utilities used across translation units, define and declare them together in an H file:

utility.h

template<class Gizmo> bool DoSomethingUseful() 
{
  // ...
}

As your templates become more complex it will become more important to be able to view the declaration seperately from the definition. At first, keep everything seperate but in the same file:

utility.h

template<class Type> class Useful
{
  bool FunctionA();
  bool FunctionB();
};

template<class Type> bool Useful<Type>::FunctionA()
{
  // ...
}

template<class Type> bool Useful<Type>::FunctionB()
{
  // ...
}

But eventually even this will become unwieldly. When it does, separate it in to a header file for the declarations, and an INC file for the definitions. At the end of the header file, #include the INC file:

utility.h :

template<class Type> class MoreUseful
    {
      bool FunctionA();
      bool FunctionB();
    };

#include "utility.inc"

utility.inc :

template<class Type> bool MoreUseful<Type>::FunctionA()
{
  // ...
}

template<class Type> bool MoreUseful<Type>::FunctionB()
{
  // ...
}
John Dibling