Proper Place to Put Definition of Templated Class Definition - c++

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.

Related

Cannot force instantiation of specialized template

In a static library I declared a template in Class.h then I specialized some methods in Class.cpp. I want to use this class in a project linking to this library.
I put the specialization in a .cpp file to avoid errors like "already declared" (???) end at the end of the same .cpp I declared the existence of the specialization once everything is known for this class. Here is the code:
Class.h
#ifndef __CLASS_H__
#define __CLASS_H__
template<class T>
class Class
{
public:
~Class(){}
Class(){}
//...
void method1()
{ /* unspecialized job here */ }
};
#endif
Class.cpp
#include "Class.h"
template<>
void Class<bool>::method1()
{
/* Specialized job for bool here */
}
// Declare that the class is specialized for bool
template class Class<bool>;
Now, in my project using the library, when I try to instantiate an object of class Class<bool>, it still use the unspecialized method.
What is the problem? Is the use of "template" at the end of the .cpp file correct?
I use gcc 4.8/4.9 on Kubuntu/Raspbian if it has an importance and I use C++11.
The template specializations
template<>
void Class<bool>::method1()
{
/* Specialized job for bool here */
}
// Declare that the class is specialized for bool
template class Class<bool>;
are seen only in Class.cpp. If Class<bool> is used anywhere else in your code, those specializations are not visible there. Hence, the generic class template is used to instantiate Class<bool>.
If you want the specializations to be visible to all the files where Class<bool> is used, move them to Class.h. At that point, Class.cpp won't be necessary any more unless it has code other than the lines above.
You need to use extern templates for the specialization to be effective.
In your cpp you have the specialization and this line:
template struct MyClass<bool>;
Then add to the header:
extern template struct MyClass<bool>;
Now the compiler will be told to not instantiate the template but to pick up the instantiated one in your cpp.

How to separate a template class from its friend template class into different header files?

A file contains template class A and template class B. A is friend of B.
I want to separate them into different files. How to deal with it?
A.h
#if !defined(FILE_A_H)
#define FILE_A_H
template<class T>
class A
{
template<class> friend class B;
// ...
};
#endif
B.h
#if !defined(FILE_B_H)
#define FILE_B_H
template<class T> class B { /* ... */ };
#endif
Note that if the name of the class that is used in the friend declaration is not yet declared, it is forward declared on the spot (see http://en.cppreference.com/w/cpp/language/friend).
Further details:
Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?
Why do I get linker errors when I use template friends?
Templates, C++FAQ

Define template in header file and definition in a cpp file within derived class [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why should the implementation and the declaration of a template class be in the same header file?
I am trying to define a template in a header file and the definition of it in a cpp file and the template should be defined within a derived class. So this is what I got:
Header file:
#ifndef ........
#define .....
template <class mytypename>
class abcBaseClass:public abcDerivedClass{
public:
mytypename getvalue(char*)
};
#endif
Source file:
mytypename abcDerivedClass<mytypename>::getvalue(char* name){
}
I just wanted to know if this is the correct way of doing it?.
This is what I am trying to achieve... The final way I want to make the call is
double x = a->getvalue<double>(char)
Similar questions have been asked many times on SO already.
But anyways...
First of all, you made some syntax errors.
Instead of
#ifndef ........
#define .....
template <class typename>
class abcBaseClass:public abcDerivedClass{
public:
typename getvalue(char*);
};
#endif
it should be something like this.
#ifndef ........
#define .....
template <typename T>
class abcBaseClass:public abcDerivedClass{
public:
T getvalue(char*);
};
// Definition follow in this file!
// For reasons or work-arounds, read below.
#endif
Also, both the template declarations and definitions should go into the same file.
One exception is when you instantiate that template to some type in the source file at where the template definition is.
Something like this.
#include "this_template.h"
template <typename T>
// all sorts of definitions...
// Explicit instantiate this template!!!!
template class abcBaseClass<Your_Type_Goes_Here>;
Note, a fundamental flaw with this approach is that, you can only use the type you explicitly instantiate in this source file everywhere else in your program. Attempting to instantiate this template with some other type will cause the linker complain about not able to find the matching definition.
If you insist on both the template being generic and having the definition of your template class somewhere else.
You can put the definition into another header file, just call it something like this_template_impl.h and include this_template.h in this_template_impl.h
Then, in your source file, instead of #include "this_template.h", you write #include "this_template_impl.h
You can put the definition in a .cpp file, but it's more trouble and not the way templates are usually done.
You need some extra code in the .cpp to convince the compiler to generate the functions with the necessary template parameter filled in. One way is to just use the function somehow:
mytypename abcDerivedClass<mytypename>::getvalue(char* name){
}
void dummy()
{
abcDerivedClass<double> temp;
temp->getvalue(NULL);
}
There's no need to actually call the dummy function, just having it there (after the template definition) is sufficient.
I'm sure there's another way to explicitly instantiate a template, but since I don't do this I can never remember.
NO this isn't the correct way:
It should be done this way:
#ifndef ........
#define .....
template <class T>
class abcBaseClass:public abcDerivedClass{
public:
T getvalue(char*)
};
#endif
and in the .cpp file:
template
T abcBaseClass::getvalue(char * ch){
}
The reason your code isn't correct is because typename is a C++ keyword. And must throw an error during compilation
You can also use:
#ifndef ........
#define .....
template <typename T>
class abcBaseClass:public abcDerivedClass{
public:
T getvalue(char*)
};
#endif
and in the C++ file:
template<class T>
T abcBaseClass<T>::getvalue(char * ch){
}

Template class for non-inline member functions

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.

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.