I was wondering that when I create an instance of a class template with specifying the template type parameter.
1) why the non-called function do not get instatiated ? .
2) dont they get compiled until I try to use it ?
3) what is the logic behind this behavior ?
Example
template <class T>
class cat{
public:
T a;
void show(){
cout << a[0];
}
void hello(){
cout << "hello() get called \n";
}
};
int main(){
cat<int> ob1; // I know that show() did not get instatiated, otherwise I will get an error since a is an int
ob1.hello();
}
Templates aren't code - they're a pattern used to make the actual code. The template isn't complete until you supply the parameters so the code can't be made ahead of time. If you don't call a function with a particular set of template parameters, the code never gets generated.
If they instantiated the entire class, then you might get invalid code.
You don't always want that.
Why? Because in C++, it's difficult (and in some cases, outright impossible, as far as I know) to say, "only compile this code if X, Y, and Z are true".
For example, how would you say, "only my copy constructor if the embedded object can be copied"? As far as I know, you can't.
So they just made them not compile unless you actually call them.
To embellish a little more: this is typically called duck typing, and the bottom line is that it allows you to write "class patterns" of which some member functions may apply when instantiated with one template type, other members may apply when instantiated with a second template type, and by only requiring the ones you actually call to compile, you get to write a lot less code for operations that wind up being common ones.
By not requiring all member functions to be compiled you get all the niceties of static type checking on the functions that actually are compiled.
For example, imagine you had:
template <typename E>
class myContainer {
// Imagine that constructors, setup functions, etc. were here
void sort(); // this function might make sense only if E has an operator< defined
E max(); // compute the max element, again only makes sense with a operator<
E getElement(int i); // return the ith element
E transmogrify(); // perhaps this operation only makes sense on vectors
};
Then you have
// sort() and getElement() makes total sense on this, but not transmogrify()
myContainer<int> mci;
// sort and max might not be needed, but getElement() and transmogrify() might
myContainer<vector<double>> mcvd;
No code is generated for cat<int>::show() because you never call it. If you did call it you would get a compilation error. Template functions which are never called do not exist.
Templates are little more than test substitution mechanisms. This makes them very powerful. You, as the programmer, may want to create a cat<int> knowing that you will never call show() or call anything else that would be invalid. The compiler lets you know if you did, so it works out nicely.
So if your question is "why does it work this way", I would ask you "why not"? It's a design choice. This choice allows me to use a template type safely and still benefit from other parts of the code. What's the harm? You also generate less code, which is a good thing, right?
Related
The C++ language allows me to write a template function that will call a method on the object that gets passed to the function.
The concern here is when I do this, my IDE (NetBeans 8.2) will complain that it can't resolve the method. This makes sense because the type that will be used for "T" is not known until I try to compile the code, but the fact that it gives me a warning makes me a little concerned about whether or not doing this is bad programming practice.
Consider the following code:
struct S1 {
void method() const {
cout << "Method called from S1!" << endl;
}
};
struct S2 {
void method() const {
cout << "Method called from S2!" << endl;
}
};
template <typename T>
void call_method(const T& object) {
// IDE reports a warning "can't resolve the template based identifier method."
object.method();
}
Usage example:
S1 obj1;
S2 obj2;
call_method(obj1);
call_method(obj2);
This code will compile and work just fine, but the IDE will always complain. Is this okay to do? Or is there a better design that I should know about to get the same desired results.
The desired result is to write a function that can use S1 or S2 objects without caring which one it is as long as they provide an interface that includes "method()".
Assume I do not have access to the source code of S1 and S2 so I can't make changes to them. (For example I cannot make them inherit from a common base class and use dynamic polymorphism instead of a template function to achieve the same effect).
This is perfectly OK and is commonly used in a lot of cases. Dealing with a generic container from the standard library or different types of iterators for example.
If the type passed in does not have an appropriate method you will get a compilation error.
If you want you can use SFINAE to make sure the type passed in is among the types you expect. Can be good or useful sometimes, but often not needed.
Update: static_assert is another useful way of putting constraints on a template as pointed out by #Evgeny
I am trying to remove virtual calls in some tight loops in C++... easy enough with CRTP or just templates in general, but obviously this requires the compiler to know the type at compile time.
In my program there are variously optimized implementations of lets say a BitSet, and the code that refers to that BitSet does so via a reference/pointer to the base class.
Now I happen to know (because my object graph is made of identified types) what sub class a particular BitSet reference is, so I can write a trivial "decoder" function that has a code path in which each BitSet type is cast to the real subclass.
I can then call a non virtual function on that type, which is great for one operation.
My problem is (my last use of C++ was about 10 years ago so I'm catching up), I have various algorithms with different inputs/outputs that make many calls to the bitset's virtual functions, so I'd like to make template versions of those algorithms, templated by actual BitSet subclass. (The alternative would be to copy the "decoder" function for every algorithm)
This requires me to pass the algorithm whether it be a templated function or a class, to the "decoder" function, and this is where I'm having trouble. I don't know what the type parameter for the BitSet is when I'm calling the decoder, and the compiler complains - If i could leave it unspecified in some way, the compiler should have all the info it needs to generate and call a specific implementation of the algorithm at each place where I have provided it with the concrete type in the "decoder" function
Here's a list of steps I'd take:
First thing is of course setting up benchmarks and a profiler. Without knowing how much you improved, it's impossible to tell whether some change was good or not.
Then, I'd consider removing all virtual stuff from the bitset class, so you have distinct concrete implementations that just have the same interface but are not derived from a baseclass. This makes it impossible to waste time in virtual function lookups.
As replacement, you could provide various decorators that you can wrap over the concrete bitset classes to make them polymorphic at runtime. This allows you to still use existing code that requires a polygorphic bitset type.
Lastly, with the help of benchmarks and the profiler, you could convert some of the functions that still take a polymorphic bitset to function templates, so you can pass the concrete bitset types as parameters. Doing this, you avoid the runtime overhead of virtual function calls for these specific function calls.
I suspect you are essentially trying the impossible: if the actual type of the parameter is not known at COMPILE TIME, you have in any case to check the type an call a different function (weather it has a different name or a same name with different template parameter does not change what the processor has to do). The fact the check happens implicitly (via v-table) or explicitly (via a case or a if-else if ... or by means of an array of function pointers :-O ) does not change the number of operation the processor has to do. You are removing v-tables and reinventing them into your own code. Quite hard that it will change something on performance.
Your decoder could have a template template parameter. I.e your decoder is templated on an algorithm class that is templated on the BitSet. The decoder then creates an instance of the algorithm class for the particular type of BitSet and executes it:
template<template<typename> typename Algorithm>
void decoder(BitSet& bitset) {
switch(bitset.type()) {
case 1:
Algorithm<VectorBitSet>()(static_cast<VectorBitSet&>(bitset));
break;
case 2:
Algorithm<ArrayBitSet>()(static_cast<ArrayBitSet&>(bitset));
break;
default:
throw std::logic_error("Unknown BitSet type");
}
}
template<typename T>
struct PrintAlgorithm {
void operator()(const T& bitset) {
std::cout << "Type: " << bitset.type() << "\n";
std::cout << "Size: " << bitset.size() << "\n";
for(int i = 0; i != bitset.size(); ++i) {
std::cout << bitset.at(i) << "\n"; // No virtual function call.
}
std::cout << "\n";
}
};
Live demo.
I have a class that is a core component of a performance sensitive code path, so I am trying to optimize it as much as possible. The class used to be:
class Widget
{
Widget(int n) : N(n) {}
.... member functions that use the constant value N ....
const int N; // just initialized, will never change
}
The arguments to the constructor are known at compile time, so I have changed this class to a template, so that N can be compiled into the functions:
template<int N>
class Widget
{
.... member functions that use N ....
}
I have another class with a method:
Widget & GetWidget(int index);
However, after templating Widget, each widget has a different type so I cannot define the function like this anymore. I considered different inheritance options, but I'm not sure that the performance gain from the template would outweigh the cost of inherited function invocations.
SO, my question is this:
I am pretty sure I want the best of both worlds (compile-time / run-time), and it may not be possible. But, is there a way to gain the performance of knowing N at compile time, but still being able to return Widgets as the same type?
Thanks!
The issue here is that if you store the widgets as the same type, then the code that retrieves the widgets from that store (by calling GetWidget) doesn't know N at compile time[*]. The code that calls the constructor knows N, but the code that uses the object has to cope with multiple possibilities.
Since the performance hit (if any) is likely to be in the code that uses the widgets, rather than the code that creates them, you can't avoid doing something in the critical code that depends on runtime information.
It may be that a virtual call to a function implemented in your class template, is faster than a non-virtual call to a function that uses N without knowing the value:
class Widget {
public:
virtual ~Widget() {}
virtual void function() = 0;
};
template <int N>
class WidgetImpl : public Widget {
public:
virtual void function() { use N; }
};
The optimizer can probably do its best job when N is known, since it can optimally unroll loops, transform arithmetic, and so on. But with the virtual call you're looking at one big disadvantage to start with, which is that none of the calls can be inlined (and I would guess a virtual call is less likely to be predicted than a non-virtual call when not inlined). The gain from inlining with unknown N could be more than the gain of knowing N, or it could be less. Try them both and see.
For a more far-fetched effort, if there are a reasonably small number of common cases you might even see an improvement by implementing your critical widget function as something like:
switch(n) {
case 1: /* do something using 1 */; break;
case 2: /* do the same thing using 2 */; break;
default: /* do the same thing using n */; break;
};
"do something" for all cases but the default could be a call to a function templated on the constant, then the default is the same code with a function parameter instead of a template parameter. Or it could all be calls to the same function (with a function parameter), but relying on the compiler to inline the call before optimization in the cases where the parameter is constant, for the same result as if it was templated.
Not massively maintainable, and it's usually a bad idea to second-guess the optimizer like this, but maybe you know what the common cases are, and the compiler doesn't.
[*] If the calling code does know the value of N at compile time, then you could replace GetWidget with a function template like this:
template <int N>
Widget<N> &getWidget(int index) {
return static_cast<Widget<N> &>(whatever you have already);
}
But I assume the caller doesn't know, because if it did then you probably wouldn't be asking...
You need to declare a non-templated type from which the templated type inherits, and then store the widgets as pointers to the non-templated base class. That is the only (type-safe) way to accomplish what you are looking for.
However, it is probably cleaner to keep the non-templated version. Have you profiled your code to see that the loops on the runtime-configured version are actually a bottleneck?
I guess the following is not an option?
template <int N>
Widget<N> & GetWidget();
Anyway, as soon as you’re managing several widget types together you cannot make them templated anymore since you can’t store objects of different type in one container.
The non-templated base class proposed by Michael is a solution but since it will incur virtual function call costs I’m guessing that making the class templated hasn’t got any benefits.
If your types are finite and known, you could use a boost::variant as an argument to your constructor.
The variant class template is a safe,
generic, stack-based discriminated
union container, offering a simple
solution for manipulating an object
from a heterogeneous set of types in a
uniform manner. Whereas standard
containers such as std::vector may be
thought of as "multi-value, single
type," variant is "multi-type, single
value."
here is some pseudo code
boost::variant< int, double, std::string > variant;
const variant foo( 1 );
const variant bar( 3.14 );
const variant baz( "hello world" );
const Widget foo_widget( foo );
const Widget bar_widget( bar );
const Widget baz_widget( baz );
Alternatively, you could use a boost::any for more flexibility.
You could write a templated GetWidget function. That would require you to know the type when you call GetWidget:
w = GetWidget<Box>(index);
So, I'm learning C++, and I've run into something which I know how to do in Java, but not in C++ :).
I have a template for a container object, which is defined as such:
template <class T>
class Container {
vector<T> contained;
public:
void add(T givenObject) {
this->contained.push_back(givenObject);
}
T get(string givenIdentifier) throw (exception) {
for (int i = 0; i < this->contained.size(); i++) {
if (this->contained[i].getIdentifier() == givenIdentifier) {
return this->contained[i];
}
}
throw new exception("An error has occured which has caused the object you requested to not be found. Please report this bug.");
}
bool empty() {
return this->contained.empty();
}
bool identifierExists(string givenIdentifier) {
for (int i = 0; i < this->contained.size(); i++) {
if (this->contained[i].getIdentifier() == givenIdentifier) {
return true;
}
}
return false;
}
};
This actually works very well, with one small issue. It comes down to two lines: the first is the template definition and the second is
this->contained[i].getIdentifer()
In Java, when declaring a Generic (template) one can define a superclass/interface which all members of T must extend in order to not create an error. However, I'm not sure of a way to do this in C++, and my concern is that coupling the implementation here to a getIdentifier method which might not be defined is bad design.
Now, it's not a huge deal if that's the case, this is just a little challenge project to help me learn the language, but I like to try to do things right. Is there a way to do what I'm thinking? I know you can do it with primitives, for instance:
template <int T>
is valid, but when I try to use a user defined class, I get a compiler error. Any suggestions?
It's not possible for you to put artificial limitations on template type parameters. If the type given doesn't support the way you use it, you'll receive a compiler error. A feature called 'concepts,' which would essentially allow this, was going to be added to the next C++ standard, but it was delayed to the next-next standard due to time constraints. If T doesn't have a visible getIdentifier() function, the instantiation won't compile.
Template parameters need to be deduced at compile time. template<int T> is valid because the first template parameter is an integer; you can instantiate it with any constant integer. If you attempted to use it with a non-const integer variable, it wouldn't compile. An instance of a class isn't a compile time constant, so it can't be used.
You've gotten a couple of other answers, both quite good (especially #dauphic's, IMO). I'd just add that the code you've given really looks an awful lot like quite an inefficient imitation of an std::map. Under most circumstances, std::map will probably work better. If you look up its interface, it'll also show you a way to decouple your container from having to specify getIdentifier() directly -- instead of directly using something like getIdentifier(), it uses a comparison functor that defaults to std::less<T>, which will (in turn) use T::operator< -- but you can also specify an entirely different comparison functor if you prefer.
I should also point out that while others have pointed out that you'll get a compile error if you use getIdentifier (or whatever) and attempt to instantiate over a class that doesn't supply it. I feel obliged to warn you, however, that the error message you get may be long, convoluted, and quite difficult to decipher. This is especially likely if there's some other type that does have a getIdentifier member available. In this case the error message you get say something like "Unable to to convert from type A to type B", where type A is whatever type you used to instantiate the container, and type B is whatever (often entirely unrelated) type that happens to have a getIdentifier member. What's happening is that the compiler sees that you've used getIdentifier, and sees that type B has that, so it tries to convert your type A object to a type B object, and finds that it can't, so that's what it tells you about in the error message.
P.S. Yes, I know this is really more of a comment than an answer. I apologize for that, but it won't really fit in a comment.
You don't have to do anything. If contained[i] doesn't have a getIdentifer() function, you will get a compile-time error (just as you would using an interface contrainst in Java, and just as you would outside of using templates).
To elaborate: If you were to write,
int x = 10;
long id = x.getIdentifer();
That would be considered a "bad design". It would just be a mistake, which the compiler will catch. That is exactly what will happen in you're example.
C++ draws a pretty stark line between compile-time polymorphism (ie Templates) and run-time polymporphism (ie inheritance). So what you want to do is not supported by the language.
One typical practice to do what you are doing is to provide, in addition to T, a type that can get an identifier of a given T. This decouples the two behaviors into two types and you can specify (in English) the interface that must be implemented.
template <class T, class StringIdForT>
class Container
{
...
bool identifierExists(string givenIdentifier)
{
StringIdForT idGetter;
for (int i = 0; i < this->contained.size(); i++)
{
if (idGetter.getIdentifier(this->contained[i]) == givenIdentifier)
{
return true;
}
}
return false;
}
};
You have a similar problem, StringIdForT must still define a specified method
I'm abusing C++ templates a little and I'm having trouble figuring something out. Let's say I have two types that really should be inherited from a base type, but for speed reasons, I can't afford to have the virtual function overhead (I've benchmarked it, and virtual calls ruin things for me!).
First, here are the two classes I have
template<class DataType> class Class1
{
//Lots of stuff here
}
template<Class DataType> class Class2
{
//The same stuff as in Class1, but implemented differently
}
In a typical oo design, Class1 and Class2 would inherit from IInterface and I could have a function that looks like this
DoStuff(IInterface& MyInterface)
{
}
But I can't do that, so I've done this
template <class C>
DoStuff(C& c)
{
}
I know it's not pretty, as there's nothing (at the compiler level) to enforce that Class1 and Class2 implement the same interface, but for speed reasons, I'm breaking some of the rules.
What I'd love to do is create a call back function on DoStuff, but I can't figure out how to make it work with the templates (especially since there's the hidden in there.
For example this works right now
DoStuff(char* filename)
{
switch (//figure out the type i need to make)
{
case 1: return DoStuff(Class1<int>(filename));
case 2: return DoStuff(Class1<double>(filename));
}
}
template<class DataType>
DoStuff(DataType* pdata)
{
return DoStuff(Class2<DataType>(pdata));
}
template<class C>
DoStuff(C c)
{
c.Print();
}
Now I know you're asking, why use Class1 and Class2? Well the underlying difference between dealing with a file and dealing with memory is so big, that it makes sense to have different classes for the different type of input (rather than just overloading the constructor and having it behave differently for the different inputs). Again, I did benchmark this and it's much faster to have the special cases handled in their own classes rather than having cases/ifs in every function.
So what I'd like to do is hide a lot of this implementation from the junior developers, I don't want them to have to create three different overloaded DoStuffs to handle the different inputs. Ideally, I'd just set up some type of callback with #defines and all they'd need to do is something like create a class called DoStuff and overload the () operator and have the functor do the work.
The trouble I'm having is that the DoStuff function that does the work is only templatized by <class C> but C itself is templatized by <class DataType> and everything I can't figure out how to pass everything around in a generic way. E.g., I cannot use template <class C<DataType>> or template<template< class DataType> class C>. It just won't compile.
Does anyone have a good trick to have a generic call back, either a function or a functor (I don't care), with this nested templated class? Basically I want something where I can write a generic function that doesn't care about the class that's storing the data and have that called by a mostly common function that figures out which class to use.
BigSwitch(CallBack,Inputs)
{
switch(//something)
{
case 1: return CallBack(Class1<Type>(Inputs))
case 2: return CallBack(Class2<Type>(Inputs))
}
}
This way I can write one BigSwitch function and have other people write the CallBack functions.
Any Ideas?
EDIT for clarification for Jalf:
I have two very similar classes, Class1 and Class2 which represent basically the same type of data, however the data store is vastly different. To make it more concrete, I'll use a simple example: Class1 is a simple array and Class2 looks like an array however rather than storing in memory is stores in a file (because it's too big to fit in memory). So I'll call them MemArray and FileArray right now. So let's say I wanted the Sum of the arrays. I can do something like this
template <class ArrayType, class ReturnType>
ReturnType Sum(ArrayType A)
{
ReturnType S=0;
for (int i=A.begin();i<A.end();++i)
{
S+=A[i];
}
return S;
}
But now, I need a way to load real data into the array. If it's a memory-based array, I'd do this
MemArray<DataType> M(pData);
and if it's file-baaed, I'd do this
FileArray<DataType> F(filename);
and both of these calls are valid (because the compiler generates both code paths at compile time)
double MS=Sum<MemArray<DataType>,double>(M);
double FS=Sum<FileArray<DataType>,double>(F);
All of this assumes that I know what the DataType is, but for a file based array, I may not know the data type until I open the file and query the header to know what kind of data is in the array.
double GetSum(char* filename)
{
int DataTypeCode=GetDataTypeCode(filename);
switch (DataTypeCode)
{
case 1: return Sum<FileArray<int>,double>(FileArray<int>(filename));
case 2: return Sum<FileArray<double>,double>(FileArray<double>(filename));
}
}
template <class DataType>
double GetSum(DataType* pData)
{
return Sum<MemArray<DataType>,double>(MemArray<DataType>(pData));
}
All of this works, but it requires writing two overloaded GetX functions and a X function for everything that I'd want to do. the GetX functions are basically the same code everytime except for the X that it calls. So I'd love to be able to write something like
double GetX(CallBackType X, char* filename)
{
int DataTypeCode=GetDataTypeCode(filename);
switch (DataTypeCode)
{
case 1: return X<FileArray<int>,double>(FileArray<int>(filename));
case 2: return X<FileArray<double>,double>(FileArray<double>(filename));
}
}
template <class DataType>
double GetX(CallBackType, DataType* pData)
{
return X<MemArray<DataType>,double>(MemArray<DataType>(pData));
}
so that I could call
GetX(Sum,filename)
then later when someone else wants to add a new function, all they need to do is write the function and call
GetX(NewFunction,filename)
I'm just looking for a way to write my overloaded GetX functions and my X functions so that I can abstract way the input/storage from the actual algorithms. Normally, this isn't a hard problem, it's just that I'm having trouble because the X function contains a template argument that itself is templated. The template<class ArrayType> also has an implicit ArrayType<DataType> hidden in there. The compiler is unhappy about that.
Focusing on the initial part of your question (why you're not just using inheritance):
A common way to do compile-time polymorphism and give access to the derived class' members through the base class is through the CRTP pattern.
template <typename T>
class IInterface {
void DoStuff() {
void static_cast<T*>(this)->DoStuff()
}
};
class Class1 : IInterface<Class1> {
void DoStuff(){...}
}
Would that solve your problem?
Edit:
By the way, I'm glad I could help, but next time please try to structure your question a bit more.
I really had no clue what you were asking, so this was just a stab in the dark, based on the first 3 lines of your question. ;)
You never really explain what you're trying to achieve, only what your non-functioning workaround looks like. Start out stating the problem, since that's what we really need to know. Then you can provide details about your current workarounds. And when posting code, add some context. Where are DoStuff() called from, and why would junior developers need to define them? (You've already done that, haven't you?)
What would said junior developers be doing with this code in the first place?
And it's confusing that you provide the specific cases (1 and 2), but not the switch statement itself (//something)
You'll get a lot more (and better and faster) answers next time if you try to make it easy for the person answering. :)
As to your question about a "generalized callback" you can use a boost::function but that essentially uses virtual functions under the covers (it may not - but at least a similar concept) so the performance difference you are looking for won't be there (in fact boost::function will probably be slower because of heap allocation).