(Can I minimize the) Footprint of template in my C++ Code? - c++

I have a large class which basically handles one buffer of variable (numeric) datatype. So it seems a good choice to use a class template with this datatype as the only parameter. I'm not experienced in C++ and I wonder/worry a bit about the "footprint" such a template makes in my code.
There are three implications of templates which in my (C++ unexperienced) eyes are not necessary and make code ugly. I tried to avoid them, but neither did I find a good example how to do it nor did I manage to find it out by myself.
So the goal of this question is: Can you either confirm the following statements or give a counterexample?
When using a class template, all class methods have to go into the header file. Even if they have no templated type in their interface or implementation.
When using a static method or member of the class, I always have to specify a template parameter (MyClass< double > :: MY_STATIC), even if the templatization does not affect any of the static properties of the class.
When using the class as a parameter for a function, I always have to give a template parameter, even when this function does not access any of the templated members? (function myFunc(MyClass< double> & myClass){ do something } )

As a general rule, don't have functions/data members in a template class which does not use the template parameters. Have a base class, put all non-template related things there, your template class should derive from it.
To answer your questions:
yes, everywhere where you need to instantiate the template, you need to see the full definition of the class and it's functions
yep, but put that into the base class
yes, see above
EDIT: One of the reasons to move to base class is code bloating (this expression actually exist, you can google it for more info): If you don't move the template unrelated code to a base class, the very same template independent code will be copied for all instantiation of your template, which means a lot of unnecessary code. If you put it to a base class, you will only have this code once.

Yes. On the plus side, the code is only generated when the metod is actually used for the specialization.
Yes. However, there is no (other then design choice) need for a static method to be a memeber of the templated class if it has no use for the templated parameter.
Yes. The size and memory layout of the structure is determined by the template parameter.

Related

Is it possible to define a non-template function that can take a templated object as a parameter

I am using a C++ class which is templated.
I instantiate two different templated version of this class:
ExampleClass<ParamType1> obj1;
ExampleClass<ParamType2> obj2;
So that I have two objects which are the same class, but with different template parameters.
I now want to be able to define a function (extremely simplified example!) that can take either obj1 or obj2 as a parameter:
int func(ExampleClassXXX obj_param)
{
return obj_param.member_operation();
}
So that I can call either func(obj1) or func(obj2.
Is this something that is possible, and if so, what is the syntax needed for the function definition to specify the obj_param parameter is "an instance of ExampleClass created with any template parameters"?
The answer to this question sort of covers the case that is one step more general - having "obj_param" be any type. Most of the details are missing from the text of that answer, it is only when you click on the "live demo" that you see they are instantiating a templated struct to be able to pass in the generic parameter, which is pretty ugly.
It seems like this should be a common thing to want to do, but Googling has failed me so far (searching for "passing templated object as function parameter")
Note that
ExampleClass<ParamType1>
and
ExampleClass<ParamType2>
are basically two different classes for the language.
You have two possibilities, in my opinion, the first being:
template<typename ParamType>
int func(ExampleClass<ParamType> obj_param){}
The second possibility is to give to ExampleClass a non-templated public base class (basically implementing type erasure) like so
template<typename T>
class ExampleClass : public ExampleClassBase{};
and then re-write the function as
int func(ExampleClassBase& obj_param){}
but you will not be able to pass by value in this case because of object slicing issues.
The template function forces you to implement the function in a header file if you want to keep it as general as possible, the non-templated base class forces you to pay for virtual function call.
Edit: as per Alan Birtles comment, if you know already all the types you will instantiate ExampleClass with you can implement each version of the function in a cpp file.
So that I have two objects which are the same class, but with different template parameters.
A contradiction right there. If the arguments are different, this is not the same class. A template is not a class, it's a mold. If you pour two different metals into it, you'd get two very different objects, despite the similar shape. They'd have different mass and density, possibly different electromagnetic properties, and so forth. A bit tangential, but it's important to differentiate the template from the things it produces, those are not the same.
This is why different specializations produced from the same template are considered different classes. They are not related under the type system, and so no function can automatically treat them as the same thing. You could create a function template, and use it to generate functions for each distinct specialization, but those too would be different functions.
If you have a part that's common to all specializations, you could refactor it out into a base class (proper class, not a class template), and have a function that accepts that.

Pure constructors in class templates

I have some code that works, and I'm not sure why. I'm instantiating a class as an immutable variable. There are no immutable constructors in the class and none are labeled as pure, but it just works anyway.
I also read that pure constructors can be used across the board for mutable, immutable, const, and shared instances
The only thing I can find on the D website is that purity is inferred in function templates. Should I assume that since my class is parameterized (or a class template) that the compiler is inferring the purity of all the methods, including the constructor?
Code below:
public class Data(size_t numInputs, size_t numTargets)
{
...
public this(in double[][] data, in bool[] filter, in bool doNorm = true)
{
...
}
}
The only thing I can find on the D website is that purity is inferred in function templates. Should I assume that since my class is parameterized (or a class template) that the compiler is inferring the purity of all the methods, including the constructor?
Yes. Since the class is a template, all the methods are also templates (consider that they have to be since the hidden this parameter's type comes from the template). Thus, their body must be available in the source. The two requirements for inferred attributes are body source available and a template parameter for them (and also the function must not try to call or inspect itself, but you don't do that either) thus it can be inferred as pure.

c++ template code order parsing/CRTP

Can someone give a hint how does compiler process expressions such as
class DerivedA: public ParentTemplateClass<DerivedA>{
}
For mee it looks like:
this boy's father is a "son" of this boy
I mean it's not obvious for me how "parsing" of the class DerivedA can be completed WITHOUT knowing the exactly "description" of parent class. Seems' it can not. So parent class must be processed before children, but in such situation parent depends on children..and I'm stuck there.
Yeah there some articles on the web which describe usage of such thing, e.g. an article about Curiously Recurring Template Pattern (
http://en.wikibooks.org/wiki/More_C++_Idioms/Curiously_Recurring_Template_Pattern) but that's not some kind of standart or smth near. There must be clear behaviour description such as operations ordering isn't it?
ANSWERED:
Thnx to everyone. Yeah forward decl analogy seems legit for me to stop damaging my brain. Templates are still state of art for me cause of its hidden sublanguage nature and i cant just g++ -E :)
After your code says class DerivedA, the symbol DerviedA is declared. At the point it can be used as a template parameter. C++ compilers do several passes on the code, so at that point in parsing the compiler will "believe" that your intention was correct and that it will eventually get the definition of that class (when it is about to instantiate the template, i.e. you actually use that type). If not, it will complain at that point. A similar thing happens if you used a forward declared class in a declaration but didn't provide a definition before using it.
At the point at which the template is instantiated, DerivedA is incomplete; it has been declared, but not fully defined. Incomplete types can be used in various ways - for example, you can declare pointers or references to them, declare functions with them as return or parameter types, and a few other things. You can't create objects, inherit from them, access their members, or in general do anything that requires more information than just the class name.
As long as the class template only does these things, there is no problem.
I think to understand how this could work, you need too understand more about C++ templates in general, than just the Curiously Recurring Template Pattern. Someone else can probably answer this better than me, but I know that C++ can't fully parse a template class definition by itself. It instantiates the template each time it is used in the code. If each class was in a separate include file, think of it like this:
#include "ParentTemplateClass.h" // C++ initially validates the template class definition's syntax.
#include "DerivedA.h" // First use of ParentTemplateClass -
// at this point it becomes fully instantiated.
The C++ parser will initially validate the template's syntax when it sees the template definition. Then, when the template is used as a base of DerivedA, the parsing continues and the template is fully instantiated. This is, of course, a simplified view of the parsing that the C++ compiler will do, and I'm sure the details vary by compiler. See also http://womble.decadent.org.uk/c++/template-faq.html#disambiguation.

turning a non-template class into a template

I have a self made data structure (for example linked list) that works well, but when I made the class I did it based around strings, but now I want to take that data structure, and use it to hold another self made data type. I know that this involves templates (the ability to take a working data structure and apply any data type to it), but I have not really worked with them.
what steps should I follow to turn a non-template class into a template class?
The main thing you need to do is put the template specification in front:
template <class T>
class A {
...
};
Then use T instead of using your string type.
There are lots of other things to consider when creating templates, but it depends on the particular situation.
You will specify your new type when you use the template:
A<MyType> my_object;
that is basic actions
Move all method definitions of your class from .cpp to .h file
Put template specifications (template <class T>) before all declarations and definitions
Change all class name specifiers to template names, i.e. A::A(){} should became A<T>::A(){}
If it required, change the names of method calls to ones with type parameters
Change all entries of the previous type to the type parameter name
can be a lot of the other things of course.

Use templates as a members when not all the details are known

Is it possible to specifiy a template as a member but not know all the details? Or rather how can I work around this.
Example doesn't work but might show you what I'm trying to achieve.
template<typename T>
struct Foo {
///blah...
};
struct Bar {
Foo* m_foo;
};
Bar in this case is a base class, and depending on the derived classes I wont know the full details of Foo
You can either make Bar a template class as well so it can pass that template argument along to Foo, or else you can make all the Foo<T> variations inherit from a common interface (in C++, an interface is just an abstract class with no implementation, all members are pure virtual functions) and then Bar can point to that interface.
The first way is better if Bar is just going to provide some functionality which will be reused by a bunch of derived classes.
The second way is better if descendants of Bar are going to be used polymorphically.
The code you have above won't work, since whenever you use a C++ template you must specify what it's arguments are. If you want to store a Foo of an unknown type, you can do so by parameterizing Bar over some type (for example, making it a template with type argument T), then having Bar store a Foo. This contrasts with other languages like Java where code like what you have outlined above is legal because templates work differently in C++. In particular, Java-style genetics just compile down to one concrete representation, then use runtime checks to verify that they're being used properly. C++ template instantiations all end up getting compiled down into separate code, and so the compiler has to be able to infer at compile-time what the argument types are (so it knows what code to generate).