Template class for non-inline member functions - c++

I am trying to follow an example here:
http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
But I dont want to inline my function definitions with my class definition.
Will I have to put
template<typename Data>
concurrent_queue<Data>::
in front of all my function defs and constructors?

Yes, you will, and the definitions will still need to be in the header file. This is why everyone uses inline definitions- because they basically have to be inline anyway.

Yes, there is no way around that syntax (except with token-producing symbol-destroying evil evil #define macros).
Personally, I either inline them in the class template declaration/definition, or for the sake of better self-documentation put the definitions into some "inl"-file, like so:
foo.h
#ifndef FOO_H
#define FOO_H
namespace bar {
template <typename T>
class Foo {
public:
Foo () ;
virtual ~Foo();
};
}
#include "foo.inl.h"
#endif // FOO_H
foo.inl.h
#ifndef FOO_INL_H
#define FOO_INL_H
namespace bar {
template <typename T>
inline Foo<T>::Foo () {
}
template <typename T>
inline Foo<T>::~Foo () {
}
}
#endif // FOO_INL_H
Note that I explicitly declare them inline then. This improves consistency of the style, and if you happen to specialize the template, you have to do it anyways:
template <>
inline Foo<int>::Foo() {
}
Without the inline, you suffer the same pain like when forgetting it on ordinary functions defined in header files (read: multiple definition errors).

The functions do not need to be inline, but it's better if they are inside the header file:
/* in .h file */
template<class T>
class A
{
public:
void f();
}
/* this also in .h file */
template<class T>
void A<T>::f()
{
}
This is often necessary to split the class and the functions to separate parts, but both of them needs to be in the header file for templates to work.

Related

Is there a way to define a function template in a header and make it inaccessible to files who include the header?

I have a class template that looks like this:
foo.h
template<class C>
class Foo
{
public:
void memberFunc();
};
#include "foo.tpp"
foo.tpp
void Foo::memberFunc()
{
...
}
Ignore the .tpp file, it's just something I do to give the illusion of separating declaration and implementation, obviously that's (kind of) not possible with templates.
My implementation file is much longer in reality, and inside it I have some global scope helper function templates that the member functions use, functions that don't make sense as member functions and that I don't want users of the class to have anything to do with.
template<class C> int helper1() { ... }
template <class C> void helper2() { ... }
template<class C>
void Foo<C>::memberFunc()
{
...
helper1<float>();
...
helper2<C>();
...
}
I do this all the time in .cpp-implementation files and I forgot that when I do it in this fake version of a .cpp file, the declaration and implementation of these little helper functions actually end up in the class template header file. This leads to users of the class template header getting their namespaces cluttered with helper functions that are useless outside the member function implementations.
Obviously I could just put them in a namespace:
namespace foo_helpers
{
template<class C> void helper1() {...}
template<class C> int helper2() {...}
}
But it still leads to outside code being able to use these functions. They only matter to the implementation of the member functions and I want that to be reflected.
When looking for a solution, I learned about the concept of unnamed namespaces. As I understand it, they only allow the current translation unit access to its contents. That sounds like exactly what I need, so I changed the helper functions to this:
namespace
{
template<class C> void helper1() {...}
template<class C> void helper2() {...}
}
But it doesn't work, the functions are still usable from files that include the header.
Is there any way to hide these helper functions from outside code?

Avoiding duplicate code in C++ template implementation

I split a generic class into a header and implementation file as follows.
Test.h:
#ifndef MY_DESCRIPTIVE_GUARD_NAME
#define MY_DESCRIPTIVE_GUARD_NAME
template<typename T>
class MyClass
{
T myObj;
public:
MyClass(T& obj);
void set(T& obj);
T get();
}
#include "Test.tpp"
#endif
Test.tpp:
template<typename T>
MyClass<T>::MyClass(T& obj) {
// implementation
}
// etc.
But as I add more methods to MyClass, I keep having to write the same boilerplate:
template<typename T> return-type MyClass<T>::method_name
With dozens of methods (not to mention if I include more template parameters), I'm writing a lot of repeated code. Should I use a macro? Suck it up? Or is there a feature in the language that allows me to package multiple method implementations in one unit, almost as if they were defined in the header file?

C++: Instantiate many templates in library

I have a library with a class templated on a size:
foo.hpp:
template <size_t N>
struct Foo {
void bar();
};
foo.cpp:
template <size_t N>
void Foo<N>::bar() {
...
};
I want the compiled version to be instatiated for a specific list of sizes which would be defined in the cpp file. In pseudocode, something like this
foo.cpp:
template <size_t N>
void Foo<N>::bar() {
...
};
for (const auto & size: {1,2,7,9})
template struct Foo<size>;
Right now, I am manually doing this (instatiating for each type), but this is error prone since I have several files that should be defined for the same size.
I am aware that I could move everything to the header file, and use some enable_if's to choose which sizes are valid. However, I want to hide the implementation details. Hence the current approach.
EDIT:
FWIW, I was hoping to avoid macros. I thought that something like this would work if you want a range of variables (e.g. 1,2,3,4...):
template<template<size_t> class E, size_t I = 1, std::enable_if_t<I >= 5> *unused = nullptr>
bool instatiator() {
return true;
}
template<template<size_t> class E, size_t I = 1, std::enable_if_t<I < 5> *unused = nullptr>
bool instatiator() {
E<I> e;
return instatiator<E, I + 1>();
}
bool unused = instatiator<Encoder>();
but I can't seem to get that working.
You could use an X macro approach for this:
valid_sizes.hpp
// Note: no include guards!!
PROCESS_SIZE(1)
PROCESS_SIZE(2)
PROCESS_SIZE(7)
PROCESS_SIZE(9)
#undef PROCESS_SIZE
foo.cpp
// ...
#define PROCESS_SIZE(n) template struct Foo<n>;
#include "valid_sizes.hpp"
bar.cpp
// ...
#define PROCESS_SIZE(n) some_other_use_of<n>;
#include "valid_sizes.hpp"
Alternatively, instead of a manual list, you could use Boost.Preprocessor:
process_sizes.hpp
#pragma once
#define PROCESS_SIZES(macro, data) BOOST_PP_SEQ_FOR_EACH(macro, data, (1)(2)(7)(9))
some header file
#define INSTANTIATE_CLASS(r, Name, size) template class Name<size>;
foo.cpp
#include "process_sizes.hpp"
// ...
PROCESS_SIZES(INSTANTIATE_CLASS, Foo)
bar.cpp
#include "process_sizes.hpp"
// ...
PROCESS_SIZES(INSTANTIATE_CLASS, Bar)
#define OTHER_SIZE_BASED_WORK(r, data, size) other_use_of<size>;
PROCESS_SIZES(OTHER_SIZE_BASED_WORK, whatever)
Note that explicit instantiation definitions must occur at namespace scope, so it's not possible put them inside a function like your attempted instantiator.
And also note that an implicit instantiation (such as would be caused by referring to the class in a context which requires it to be defined) is not "visible" outside the translation unit, so it cannot be used as a substitute for explicit instantiation.
In other words, having the same list of sizes do different things requires duplicating the list for each use, using macros, or using custom code generation outside of the C++ compilation pipeline. I consider macros the simplest and most maintainable of these.
In addition to #Angew answer:
xmacros can be in a different manner, allowing include guards and also avoiding having #include in the middle of the code:
valid_sizes.hpp
#pragma once
#define SIZES_TABLE(OP)\
OP(1) \
OP(2) \
OP(12)
foo.cpp
#include "valid_sizes.hpp"
// ...
#define INSTANTIATE(Size) template struct Foo<Size>;
SIZES_TABLE(INSTANTIATE)
#undef INSTANTIATE
You can recursively instantiate the Foo class with a helper class. Unfortunately you need to provide a call to each method of Foo in the constructor (the methods will not be called though), in order to provide the definitions to the linker:
// foo.cpp:
template <size_t S>
struct recursive_helper {
Foo<S> foo;
recursive_helper<S-1> r_helper;
recursive_helper() {
foo.bar();
foo.baz();
}
};
template <>
struct recursive_helper<0> {
Foo<0> foo;
recursive_helper() {
foo.bar();
foo.baz();
};
};
And then you instantiate the helper class:
template struct recursive_helper<6>;

Proper Place to Put Definition of Templated Class Definition

Is it proper to define your class outside of the pound defines for a class or do they go inside the pound defines? Examples of what I am asking can be seen below.
#ifndef CLASS
#define CLASS
template <typename T>
Class
{
Class();
};
template <typename T>
Class::Class()
{
}
#endif
---Or--
#ifndef CLASS
#define CLASS
template <typename T>
Class
{
Class();
};
#endif
template <typename T>
Class::Class()
{
}
I would define it within the include guards (pound defines) to avoid multiply defined symbols. So for template classes, as in your example, I would always define it within the include guards since they always have to be defined in header files.
For other non-template classes I might define member functions in a source (.cpp) file, so this would obviously be outside the include guards.
As a footnote I'd also point out that for such a simple constructor I'd actually define it within the class declaration, or even not define it at all, but I'm guessing your actual code is a little more complex than the example given.

Where to define C++ class member template function and functors that instantiate it?

I have a class Foo which is used in a small standalone project. It has a class definition in Foo.h with the implementation for the class' member functions in an implementation file Foo.cpp.
First question - one of the member functions of class Foo is a template method Foo::doSomething(), is it correct that the implementation of this method should appear with the declaration of the function in Foo.h ?
The template parameter which Foo::doSomething() will be instantiated with is one of two Functor types - class CalcA and CalcB.
Should I:
(A) put the defintion and implementation of the two Functor classes all together in Foo.cpp (where they are actually used by the implementation of other Foo member functions to call Foo::doSomething).
(B) put the definition and implementation of the two Functor classes in Foo.h.
(C) should I put split the definition and implementation of the two Functors across Foo.h and Foo.cpp as would be done with an ordinary class?
General rule:
If foo::doSomething() is used outside foo.cpp (i.e. if it's public or protected, usually), it must go in the header.
If not, putting in in the cpp file is perfectly ok, and even a good idea (as it keeps the clutter away from the header file).
So, if the functors are only used in the cpp file, by all means put the template function there too. One can always refactor things later if this changes.
First you must understand templates mechanism. Templates are not compiled, they are instantiated when they are used and then their instantiation is compiled. So the compiler needs to have the full template definition in each module using the template function, in order to instantiate them first according to the parameters you've passed.
To solve your problem, there are three solutions but you'll see that they both lead to the same result.
Either you implement your whole templates in your header file inside the class definition (we use to suffix them with .hxx instead of .h in order to precise they're containing templates definitions):
// Foo.hxx
#ifndef __FOO_HXX__
#define __FOO_HXX__
class Foo {
public:
template <class T>
void bar(const T& t) {
t.doSomething();
}
};
#endif
Or you can externalize the definition from the class, but still in the header file:
// Foo.hxx
#ifndef __FOO_HXX__
#define __FOO_HXX__
class Foo {
public:
template <class T>
void bar(const T&);
};
template <class T>
void Foo::bar(const T& t) {
t.doSomething();
}
#endif
Finally, you can implement template methods bodies in an external file (prefixed with .cxx for the same reason). It will contain methods' bodies but won't include "Foo.hxx". Instead, it's "Foo.hxx" that will include "Foo.cxx" after the class definition. This way, when the compiler resolves the #include directive, it finds the whole template definition in the same module, allowing it to instantiate it:
// Foo.hxx
#ifndef __FOO_HXX__
#define __FOO_HXX__
class Foo {
public:
template <class T>
void bar(const T&);
};
#include "Foo.cxx"
#endif
// Foo.cxx
template <class T>
void Foo::bar(const T& t) {
t.doSomething();
}
The choice between these 3 ways to implement templates is rather a matter of readability (and taste).
Second and third are equivalent in terms of generated code, but I'd rather not use the cxx file solution, because it often leads to stupid errors when you forget to invert the include.
Moreover, well-known C++ libraries like STL or Boost propose their code in header files only, which is a sign of good design. By using external definition inside headers, you clarify the definition of your class. You also prevent the compiler to automatically inline methods, which can sometimes lead to poor results according to Herb Sutter http://www.gotw.ca/gotw/033.htm
My default would be to put the definition for the member function templates right in the .h file, like this:
class Foo
{
public:
template<typename T> void DoSomething(T t);
};
// ... later...
template<typename T>
void Foo::DoSomething(T t)
{
// ...
}
If this is suboptimal for a particular case, then I'd take more heroic measures. Starting with #include-ing a .inc file with the definition at the end of the .h file, or possibly even doing explicit instantiations in the .cpp files where I needed the member function templates to be used.
The template method definition should indeed be in the header file of it the class it belongs to.
Like this:
class MyClass
{
template <typename T>
void foo(const T&)
{
// Definition
}
};
Or like this (note that the template method definition can be included from separate file after the class declaration)
class MyClass
{
template <typename T> void foo(const T&);
};
template <typename T>
void MyClass::foo(const T&)
{
// Definition
}
The rest is depends on the style you agreed on and your needs.
I would put the functor declaration (or even the definition if they are simple) into the header if I use them not only in Foo or if Foo has them as class member.