-2

I have searched a lot on this topic. I came across three methods. Suppose we have 3 files, the main.cpp, the declaration header file and the definiton cpp file. The first method suggests to create a temporary opject in the cpp file. The second method suggests to include both cpp and header files in our main file. The third method suggests to include the cpp file in the header file.

Now the question: which one is the best method ? by saying best I mean both good in performance and good at proper code styling. Are there any other better methods?

David Safrastyan
  • 725
  • 7
  • 18
  • I would say no *performance* differences, but not 100% sure. The rest is opinion-based, and in my opinion, including `cpp` files is ugly – Яois Apr 01 '15 at 18:37
  • To me it is not clear at all what you are asking. Templates typically dont have a cpp. Maybe you can put a little example code. – 463035818_is_not_an_ai Apr 01 '15 at 18:37
  • Also, I dont understand what you mean with "creating a temporary object in the cpp file". Can you put links, where did you find these three methods? – 463035818_is_not_an_ai Apr 01 '15 at 18:40
  • see e.g. [here](http://www.parashift.com/c++-faq/templates-defn-vs-decl.html) or [here](http://stackoverflow.com/questions/2185954/implications-of-template-declaration-definition) – 463035818_is_not_an_ai Apr 01 '15 at 18:41
  • @tobi303 you may find many examples here in SO http://stackoverflow.com/questions/115703/storing-c-template-function-definitions-in-a-cpp-file – Яois Apr 01 '15 at 18:41
  • well, ok. Then I would actually vote to close this question. Or the question should be rephrased to something that isnt covered in the other questions already. – 463035818_is_not_an_ai Apr 01 '15 at 18:45
  • this question actually *screams* "opinion-based" – Яois Apr 01 '15 at 18:49
  • Sometimes `.icc` or `.tcc` is used as extension to C++ file (instead of `.cpp`) with template function definitions included in a header (after the class definition). – tmlen Apr 01 '15 at 18:50

2 Answers2

1

Templates should always be defined inside class body. This is the most preferred solution, because it's simple, clear and allows you to avoid a lot of unnecessary typing.

Consider following class:

template <CharEncoding Encoding>
class UnicodeConverter
{
protected:
    template <typename Input_char_type, typename Output_char_type>
    class InternalHelper
    {
    public:
        void function_a()
        {
            //do something
        }
    };

    //...
};

Now imagine, what would you have to write if you wanted to have a separate definition file:

template <CharEncoding Encoding>
template <typename Input_char_type, typename Output_char_type>
void UnicodeConverter<Encoding>::InternalHelper<Input_char_type, Output_char_type>::function_a()
{
  //do something
}

That is definitely not pretty nor readable, wouldn't you agree?

There are some situations, where definition must separated (for example, two templates, that depend on each other), but in most cases: avoid it!

The rule of placing implementation in separate .cpp files, generally does not apply to templates. C++ standard library also is mostly header-based, as its extensively uses templates for everything.

Also, note, that my sample code is a real sample, taken from real app (slightly modified). And imagine, that this is not the most complicated template I have in this project.

Mateusz Grzejek
  • 11,698
  • 3
  • 32
  • 49
  • Doesn't including the function definition inside the class body indicate it should be inlined? – tmlen Apr 01 '15 at 18:48
  • No. Forget about this whole "inlining-hint". Compiler doesn't care what you think about inlining, he can do much more better than you in judging this kind of optimizations. `inline` is keyword used by linker. It tells him, that multiple definitions of a certain functions (if encountered) should not be treated as an error and allowed. There two major techniques for dealing with such situations: `1.` treating function as declared with `static` storage specifier or `2.` act wisely and merge all these copies into one. All this happens, if compiler hasn't inlined this function. – Mateusz Grzejek Apr 01 '15 at 18:55
1

The first method suggests to create a temporary opject in the cpp file.

?

The second method suggests to include both cpp and header files in our main file.

Most compilers do not support splitting template code in this manner. It would require the use of external template definitions, which is not widely supported yet. Most compilers require templates to be declared and defined in the same translation unit. Which brings us to the 3rd option...

The third method suggests to include the cpp file in the header file.

This is the approach most people take, if they even split their template declarations from definitions at all (see 4th option below). However, it is common to name the definition file with a .icc file extension instead of .cpp to make this distinction clearer. For example:

myfile.h:

template<typename T>
class TMyClass
{
public:
    void doSomething(T value);
};

#include "myfile.icc"

myfile.icc:

template<typename T> void TMyClass<T>::doSomething(T value)
{
    //...
}

Which brings us to the 4th option - not splitting the code at all, but implement it inline instead. This is the more common way to write templates. For example:

myfile.h:

template<typename T>
class TMyClass
{
public:
    void doSomething(T value)
    {
        //...
    }
};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770