0
votes

A very common coding practice is to separate the interface of a class from the implementation of its member functions through the use of .h and .cpp files on a per-class basis. So class Foo would be realised with a Foo.h header file and a corresponding Foo.cpp file.

This is often thrown out of the window in the special case of generic classes and instead header-only libraries are used to keep the compiler happy even though it does clutter the interface file with implementation details.

I've recently come accross some code written as follows. The .h file contains the interface and a #include to a .hpp file which contains the implementation of the generic member functions.

e.g. for a simple container of type T Value.h

#ifndef VALUE_H
#define VALUE_H

template <typename T>
class Value
{
public:
    Value(T value);
    void set(T value);
    T get() const;
private:
    T data;
};

#include "Value.hpp"

#endif

and the corresponding Value.hpp

#ifndef VALUE_HPP
#define VALUE_HPP

template <typename T>
Value<T>::Value(T value) : data(value)
{
}

template <typename T>
void Value<T>::set(T value)
{
    data = value;
}

template <typename T>
T Value<T>::get() const
{
    return data;
}

#endif

This has the advantage of better separating interface and implementation coupled with the further benefit of actually compiling (in my limited testing).

My question is then are there any hidden pit-falls with adopting this convention?

2
I think the separation you've achieved is an illusion. But if you're happy with it then go for it. BTW I believe you still need to mark your implementation methods as inline, templates or not they are still in a header file. - john
AFAIK no, but i would choose a more commonly used file extension like .tcc and the include guard for the implementation file is superflouus. - πάντα ῥεῖ
It looks to me like this used to be a .h and a .cpp, but then the programmer realized that the template methods wouldn't be instantiated in the .cpp file, so they were moved to a .hpp instead. Splitting it like this does nothing for you. - Peter
@Peter isn't there some advantage in terms of ease of use in that a client programmer using the class can more easily separate the observable semantics of the class from its implementation details? - DuncanACoulter

2 Answers

2
votes

Since you need to include both "value.h" and "value.hpp" in every file that uses the Value class, there is no benefit in compile time. But if you mean "it compiles" vs a solution where you put the implementation in a .cpp file, then yes, there is a benefit.

There is of course a benefit in that you can easily see the interface(s) provided by the class, without having the file cluttered up with a bunch of implementation code.

I'm not sure the naming convention of "value.h" and "value.hpp" is the 'best' choice. I think the "value.inl" is a better name for the second file.

1
votes

No there are no special pitfalls with this solution. The .hpp file is just another header file which contains the definitions for the methods declared by the templated class. Since methods of templated classes needs to be defined in the header file this is a convenient method for separating the declaration from the definition. The extension .hpp shows that it is a hybrid of header and implementation file and is commonly used.