Template class in C++ - c++

We have following class definition
template<typename T>
class Klass {...}
and we also have below two instantiations
Klass<int> i;
Klass<double> d;
how many copies of Klass' methods are generated by the C++ compiler?
Can somebody explain it? Thanks!

Klass isn't a type, so it doesn't make sense to talk of Klass's methods. Kalss<int> is a type with it's own methods, and so is Klass<double>. In your example there would be one set of methods for each type.
Edit in real life, it isn't as simple as that. The question of the actual existence of the methods also depends on other factors, see #KerrekSB's answer to this question.

Each template instance is an entirely separate, distinct and independent type of its own. However, the code for class template member functions is only generated if the member function is actually used for a given template instantiation (unless you instantiate the template explicitly for some set of parameters). Among other things, this means that if some class template member function's body doesn't actually make sense for a given template parameter, then you can still use the overall template as long as you don't invoke that member function, since the code for the member function will never get compiled.
Also bear in mind that templates can be specialized:
template <typename T> struct Foo {
int bar;
void chi();
};
template <> struct Foo<int> {
double bar(bool, char) const;
typedef std::vector<bool> chi;
bool y;
};
As you can see, there's a lot you cannot just tell from a template itself until you see which actual instantiations you'll be talking about.

Related

C++ conditional template class definition of member function

Given the following class forward declaration in a header file:
template <typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
class context
{
public:
context();
// ....
private:
// ....
T data;
}
How can I define the constructor (or any other member function) in the cpp file? Tried everything I can think of but nothing matched....
This other question was brought to my attention Why can templates only be implemented in the header file? and I have successfully used the methodology suggested in the accepted answer in multiple places in my project, however I can not find a way to represent the second template parameter in any way... that question does not provide enough information to do that. The problem is here the second template parameter makes that either incompatible with the suggested way there or I just could not find the appropriate syntax to represent it, if my class would have just the first parameter it would answer it...
P.S. Sorry if this is a duplicate, I really tried to find a similar question just could not find the appropriate terminology to find a match.
To supply an out of class definition, the template parameter list must match.
template<typename T, std::enable_if_t<std::is_integral_v<T>, int> N>
context<T, N>::context() {
}
The parameter type is std::enable_if_t<std::is_integral_v<T>, int> in the class template definition. And that's exactly what needs to be the type of the parameter in the out of class definition.
As an aside, I don't see a benefit for the check being where it is currently. Unlike function templates, where this may affect overload resolution, class templates don't benefit much if at all from the mechanism. IMO it would be preferable to simply add a static assertion to the class template declaration
template<typename T>
class context {
static_assert(std::is_integral_v<T>, "Must be initialized with an integral type");
// ...
};
Then the out of class member declarations become much more straight forward. And error messages about bad template arguments are much more readable.

Function definition in a template class

Usually, one declares a member function in a header file and uses a source file to implement it. My understanding of the reason is that the function implementation will reside in only one translation unit and will be just linked to other units (no duplicate code), and it also allows separation of the interface and implementation, and removes the need to forward declare functions that depend on each other.
However, member functions in a template depend on the template arguments, which couldn't be known if the implementation was placed in a source file. However, it is still possible to define such functions outside the class, but the major argument for it doesn't apply anymore.
So, which is better?
template <class T>
class A
{
T m()
{
return T();
}
};
or
template <class T>
class A
{
T m();
};
template <class T>
T A::m()
{
return T();
}
These two pieces of code would be equivalent if it was inline T A::m(), but is there any difference without it? What if the function is virtual? Is it just a matter of coding style, or does it have different semantics? If the function is large enough, will it prevent duplicate code, or is the compiler smart enough not to inline it if it won't bring any benefits?
These two pieces of code would be equivalent if it was inline T A::m(), but is there any difference without it?
Not for templates, the member functions are implicitly inline, for both inside and outside the class definitions.
What if the function is virtual?
Makes no difference.
Is it just a matter of coding style, or does it have different semantics?
Mostly stylistic. However, it affects how name lookup works. So if we were to modify the class definition a bit
template <class T>
class A
{
using foo = T;
foo m();
};
We would not be able to define the member outside as
template <class T>
foo A<T>::m()
{
return T();
}
Since the lookup for foo doesn't happen inside the class definition until after the qualification A<T>::. We'd need to either fully qualify foo itself, like so typename A<T>::foo. Or perhaps use a trailing return type.
If the function is large enough, will it prevent duplicate code, or is the compiler smart enough not to inline it if it won't bring any benefits?
Neither style should have either an adverse of positive effect on it. Both are subject to quality of implementation issues. But of course, different implementations may have different qualities.

class template vs. member template

Is there a good rule when to use a class template instead of using member templates?
As I understand it, your are forced to use a class template if your class contains member variable templates but otherwise you are free of choice since this:
template<typename T>
class Foo
{
public:
void someMethod(T x);
};
behaves like this:
class Foo
{
public:
template<typename T>
void someMethod(T x);
};
Is my claim wrong? Or is there any rule of thumb when to use what?
The two are not at all the same. With the first:
Foo<int> f;
f.someMethod('a');
the called function is someMethod(int).
With the second:
Foo f;
f.someMethod('a');
the called function is someMethod(char).
You can choose to make your class a template, rather than having member function templates, for several reasons. Say you have a template parameter T.
Like you said, if you have a member variable of type T, your class needs to be a template.
If you have a function returning T and not accepting T, and you don't want to manually specify the type in each invocation, your class needs to be a template.
If you need a virtual function that depends on T, your class needs to be a template.
If you need a different class layout (i.e. member variables) per instantiation of T, your class needs to be a template.
If you need to make sure that your functions all operate on a single type rather than generate different versions of them arbitrarily, your class needs to be a template.
The best rule of thumb would be to use the simplest thing that makes sense. In general, member function templates tend to be more rareā€”and virtually non-existent for the use case you're talking about. Maybe that's no coincidence.

confused with template class in C++

I know that the template class definitions is like:
template <class TYPE>
class cars{
public:
TYPE myCar;
}
but somewhere I encountered to this piece of code:
template <class T>
class polynomialT {
...
}
**************************************
class GFNUM2m {
...
}
**************************************
template class polynomialT<GFNUM2m>;
the last line is vague for me? any one knows what's up? is it an object of polynomialT class?(it seems not because it has no name) is it template?(it seems a duplicate because it has been templated once)
template class polynomialT<GFNUM2m>;
Is a request to explicitly instantiate the template class polynomialT with GFNUM2m, including instantiating all its non-template functions.
Some cases when this is needed are:
When you want to avoid multiple template instantiation (that then get purged by the linker);
When you want to make sure that the full template can be instantiated even for those (non-template) functions not called;
When you want to provide template definitions within a .cpp file;
the last line is equivalent to:
class polynomialT {
protected:
GFNUM2m *coeff; // array of coefficients (? see below)
int degree;
...
}
GFNUM2m *coeff is not an array, is simply a pointer to a GFNUM2m variable. Array and pointer are linked in some way, for example you can allocate dynamically an array with coeff = new GFNUM2m[10], but it is discouraged.
In fact, it is _explicit template instantiation. Use this to get the compiler to generate all (non-nested-template) members of the template class. This is convenient sometimes when linking externally to templated code, to prevent duplication of object code or missing externals (when methods get inlined).
Template specializations seem similar, but require template<> to announce the specialization of an already-declared template. Also, they would define an alternative class definition for that specific template parameter (as #rerun mentions).
Now, on the crosspoint of those, you could see
template<> class polynomialT<GFNUM2m>;
Which IS, in fact, a forward declared template specialization. This would serve to prevent the compiler from auto-instantiating the class template for that type parameter during the rest of the translation unit.
The last line is a forward declaration of the polynomialT class template with a template parameter of GFNUM2m, which also instantiates the template class.
it means template in the class polynomialT is now GFNUM2m class.

C++ partial template specialization

Is this answer considered "good" code or is it just an ugly hack?
And I would like to know how this is forward-declared (both classes).
When I just forward-declare the class with 2 template-parameters, it just always takes this one, no matter what value flag has.
I would like to do this because I have 2 special member functions which should behave differently on flag being true and I don't feel like reimplementing the whole class. Also, it should have the same name. According to this example, this seems to be possible.
And I have to forward-declare it because I'm creating a library in which we forward-declare everything.
Any idea?
It has the drawback that it doesn't really work. The base member function is not overridden, but it is just hidden by the derived class' function when you try to call it from outside. Which means if you call doSomething out of the base class (where presumably all your other functions live) it will call the base class doSomething which is not what is wanted.
The accepted answer on that question shows multiple ways for how you can solve your problem.
In order to use specialisation its definition always has to be visible to the caller. If, for example, you have template <class Type, bool flag> struct something defined in one header and template <class Type> struct something<Type, true> : public something<Type, false> defined in the second one, to use the latter you have to include the second header. Without that you will always get the first, more generic type.
EDIT: the bit about forward-declaring got me thinking. If you want to use only type declaration, as in pointer variable, do the following:
Header
template <class Type, bool flag>
struct something;
struct Test
{
something<int, true>* ptr; // definition not needed
Test();
}
Source
#include "something.h" // header with template
#include "something_spec.h" // header with specialisation
Test::Test()
{
ptr = new something<int, true>(); // specialisation used
}