How to call a template member function from the <class T> class - c++

First my code, better to ask the question with code visible.
template<class T>
class TemplateClass
{
public:
TemplateClass()
{
};
~TemplateClass(){};
T cc{this};
void tbcFunction(){};
void otherFunction(){};
};
class CallerClass
{
public:
CallerClass(TemplateClass<CallerClass>* tc) : templatePointer(tc){};
~CallerClass(){};
TemplateClass<CallerClass>* templatePointer;
void myFunction()
{
templatePointer->tbcFunction();
};
};
void setup()
{
TemplateClass<CallerClass> ct;
ct.otherFunction();
}
I need to call a function from TemplateClass from the code in CallerClass.
One way to achieve that is to provide the "this" from TemplateClass to the CallerClass when instantiating.
That is the solution I have done above with passing it within the constructor.
Are there any negative effects when doing it this way ?
Are there other/better/more elegant solutions for this ?

Related

Derived from template class?

I'm trying to use the following code, but can't get it to complete.
Can anyone see the problem?
class IResourceJob
{
public:
virtual ~IResourceJob() {}
virtual void execute() = 0;
};
template<typename T>
class ResourceJob : public IResourceJob
{
public:
void execute()
{
static_assert(false, "Specialised ResourceJob<T> not defined!");
}
};
template<>
class ResourceJob<int>
{
public:
void execute()
{
// test.
}
};
The following usage gives a compile error:
IResourceJob* job = new ResourceJob<int>;
Thanks!
The compiler gives an error for any template that can never be instantiated. For your member function of the class template (i assume you mean static_assert), that is true, so the compiler is in right to give you a diagnostic.
You want to make the condition depend on T and cleverly make it always evaluate to false when instantiated. For example like
template<typename T>
struct always_false : std::false_type {};
template<typename T>
class ResourceJob : public IResourceJob
{
public:
void execute()
{
static_assert(always_false<T>::value,
"Specialised ResourceJob<T> not defined!");
}
};
Since the compiler cannot know whether the user will put a specialization of always_false (which you won't, of course), it cannot early-reject the template anymore.
I also doubt that you wanted to put the static_assert into execute, since your error message indicates that ResourceJob as a whole needs to be specialized. So put the static_assert outside of the member function into the class body. If you don't want the user to specialize the whole template, but only the member function, the user instead needs to say
// either "inline" and in the header, or not "inline" and in the .cpp file, but then
// put this into the header: template<> void ResourceJob<int>::execute();
template<> inline void ResourceJob<int>::execute() {
}
This will provide an alternative definition of execute which will be used by the template if T is int.
IResourceJob* job = new ResourceJob<int>;
fails because the class ResourceJob<int> is not derived from from IResourceJob.
The code should be
template<>
class ResourceJob<int> : public IResourceJob
{
public:
void execute()
{
// test.
}
};
You need to derive the template specialization as well, as in:
template<>
class ResourceJob<int> : public IResourceJob
{ /* ... */ };

How to simulate virtuality for method template

I have a class hierarchy where I want to introduce a method template that would behave like if it was virtual. For example a simple hierarchy:
class A {
virtual ~A() {}
template<typename T>
void method(T &t) {}
};
class B : public A {
template<typename T>
void method(T &t) {}
};
Then I create object B:
A *a = new B();
I know I can get the type stored in a by typeid(a). How can I call the correct B::method dynamically when I know the type? I could probably have a condition like:
if(typeid(*a)==typeid(B))
static_cast<B*>(a)->method(params);
But I would like to avoid having conditions like that. I was thinking about creating a std::map with typeid as a key, but what would I put as a value?
You can use the "Curiously Recurring Template Pattern"
http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
Using this pattern, the base class takes the derived class type as a template parameter, meaning that the base class can cast itself to the derived type in order to call functions in the derived class. It's a sort of compile time implementation of virtual functions, with the added benefit of not having to do a virtual function call.
template<typename DERIVED_TYPE>
class A {
public:
virtual ~A() {}
template<typename T>
void method(T &t) { static_cast<DERIVED_TYPE &>(*this).methodImpl<T>(t); }
};
class B : public A<B>
{
friend class A<B>;
public:
virtual ~B() {}
private:
template<typename T>
void methodImpl(T &t) {}
};
It can then be used like this...
int one = 1;
A<B> *a = new B();
a->method(one);
Is there any common code you could extract and make virtual?
class A {
virtual ~A() {}
template<typename T>
void method(T &t)
{
...
DoSomeWork();
...
}
virtual void DoSomeWork() {}
};
class B : public A {
virtual void DoSomeWork() {}
};
As you may know, you cannot have templates for virtual functions, since the entirety of the virtual functions is part of the class type and must be known in advance. That rules out any simple "arbitrary overriding".
If it's an option, you could make the template parameter part of the class:
template <typename T> class A
{
protected:
virtual void method(T &);
};
template <typename T> class B : public A<T>
{
virtual void method(T &); // overrides
};
A more involved approach might use some dispatcher object:
struct BaseDispatcher
{
virtual ~BaseDispatcher() { }
template <typename T> void call(T & t) { dynamic_cast<void*>(this)->method(t); }
};
struct ConcreteDispatcher : BaseDispatcher
{
template <typename T> void method(T &);
};
class A
{
public:
explicit A(BaseDispatcher * p = 0) : p_disp(p == 0 ? new BaseDispatcher : p) { }
virtual ~A() { delete p_disp; };
private:
BaseDispatcher * p_disp;
template <typename T> void method(T & t) { p_disp->call(t); }
};
class B : public A
{
public:
B() : A(new ConcreteDispatcher) { }
// ...
};
Oops. Initially answered at the wrong question - ah well, at another question
After some thinking I recognized this as the classic multi-method requirement, i.e. a method that dispatches based on the runtime type of more than one parameter. Usual virtual functions are single dispatch in comparison (and they dispatch on the type of this only).
Refer to the following:
Andrei Alexandrescu has written (the seminal bits for C++?) on implementing multi-methods using generics in 'Modern C++ design'
Chapter 11: "Multimethods" - it implements basic multi-methods, making them logarithmic (using ordered typelists) and then going all the way to constant-time multi-methods. Quite powerful stuff !
A codeproject article that seems to have just such an implementation:
no use of type casts of any kind (dynamic, static, reinterpret, const or C-style)
no use of RTTI;
no use of preprocessor;
strong type safety;
separate compilation;
constant time of multimethod execution;
no dynamic memory allocation (via new or malloc) during multimethod call;
no use of nonstandard libraries;
only standard C++ features is used.
C++ Open Method Compiler, Peter Pirkelbauer, Yuriy Solodkyy, and Bjarne Stroustrup
The Loki Library has A MultipleDispatcher
Wikipedia has quite a nice simple write-up with examples on Multiple Dispatch in C++.
Here is the 'simple' approach from the wikipedia article for reference (the less simple approach scales better for larger number of derived types):
// Example using run time type comparison via dynamic_cast
struct Thing {
virtual void collideWith(Thing& other) = 0;
}
struct Asteroid : Thing {
void collideWith(Thing& other) {
// dynamic_cast to a pointer type returns NULL if the cast fails
// (dynamic_cast to a reference type would throw an exception on failure)
if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
// handle Asteroid-Asteroid collision
} else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
// handle Asteroid-Spaceship collision
} else {
// default collision handling here
}
}
}
struct Spaceship : Thing {
void collideWith(Thing& other) {
if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
// handle Spaceship-Asteroid collision
} else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
// handle Spaceship-Spaceship collision
} else {
// default collision handling here
}
}
}
I think the only solution is the http://en.wikipedia.org/wiki/Visitor_pattern
See this topic:
How to achieve "virtual template function" in C++

c++ template problem

i have a class which has a template by other purposes:
template<class t>
class MyClass {
public: //of course public...
t foo;
std::string text;
}
and i have another class which method get all kind of these class through the arguments, and want to store the pointer in an array. The class dont want to access the specific (tempalted) parts of the classes only the common attributes/methods.
class Container {
public: //of course public...
MyClass* array; //this is allocated with some magic.
void bar(MyClass& m) {
and want to store the class in a MyClass* array.
}
}
here is the error that argument list for template missing
how can i solve this?
The simplest method would be to make that function a template as well:
template <class t>
void bar(MyClass<t>& m) {
// ...
}
Note that that should probably be const MyClass<t>&, because you don't need to modify it.
Your new code is meaningless. There is no such that as an object of type MyClass, because MyClass is a template. If you want to operate on these classes irrespective of their template argument, then you need to factor out the non-template portions as a base class:
class MyClassBase
{
public:
// polymorphic base classes should always have virtual destructors
~MyClassBase() {}
virtual void some_function() = 0;
};
template <typename T>
class MyClass : public MyClassBase
{
public:
// implement abstract functions
void some_function()
{
// template argument T is available here
}
};
Then you can refer to that base, and when you call a virtual function it will dynamically dispatch:
class Container
{
public:
// no magic: use a std::vector for dynamic arrays
std::vector<MyClassBase*> array; // not by value! avoid slicing
void bar(MyClassBase& m)
{
array.push_back(&m);
}
void baz()
{
array[0]->some_function(); // for example
}
};
How about putting a common base class.
class MyClassCommon {
protected:
~MyClassCommon() { }
public:
std::string text;
};
template<class t>
class MyClass : public MyClassCommon {
public: // of course public...
t foo;
};
class Container {
public: // of course public...
MyClassCommon* array; // this is allocated with some magic.
void bar(MyClassCommon& m) {
/* ... */
}
};
If you want to create a "multi-template" array, you'd better use a non-template class as a base class of a template class. Or you can make a template array and store any objects in it.
the text variable in your class is private so unless you bar function is a method of the class you can't legally use it like that

class containing a generic type of a child

Is there any possible way that a generic type can be used to contain a child of a base class.
From the assignment given to me, I am to create something similar to the following in structure.
template <class T>
class Fruit {
private:
int count;
int location_id;
T type;
public:
virtual void displayInfo();
};
class Apple : private Fruit<Apple> {
private:
int variety;
public:
void displayInfo() {
printf("Location %i has %i of %s in stock", location_id, count, variety);
}
};
Fruit<Apple> appleinventory[SIZE];
Basically, I think you can't have a template generic type be the same as a derived class. Am I wrong? Is there something similar that would possibly work?
Update:
For the assignment, I believe we are to use inheritance to show use of virtual functions. I've updated the code above. I think this would work, but does NOT need templates to be successful. We have not covered any advanced, redundant inheritance methods in class.
This is perfectly fine, in principle.
Read up about Curiously Recurring Template Pattern (CRTP) for more info on usage of derived class as the instantiating type in a class template that is its base, esp the example about static polymorphism which should look 'curiously' familiar.
template <class Derived> struct Base
{
void interface()
{
// ...
static_cast<Derived*>(this)->implementation();
// ...
}
static void static_func()
{
// ...
Derived::static_sub_func();
// ...
}
};
struct Derived : Base<Derived>
{
void implementation();
static void static_sub_func();
};
Ignoring questions of why you want to do this....you can get some of the way by doing this following:
template <class T> class Fruit
{
private:
int count;
int location_id;
T* type;
};
class Apple : private Fruit<Apple>
{
private:
int seeds;
bool red;
};
Fruit<Apple> appleinventory[SIZE];
Note the T* type is now a pointer to Apple rather than an instance of Apple.

Overriding a templated class function

I'm trying to create some kind of callback for a class template. The code is like this:
template <typename t>
class Foo {
void add(T *t) {
prinf('do some template stuff');
on_added(t);
}
void on_added(T *t) { }
}
struct aaa {}
class Bar : Foo<aaa> {
void on_added(aaa *object) {
printf("on added called on Bar");
}
}
the on_added function on Bar never gets called. What would be the best way to add a callback that a template subclass could optionally override? Thanks
Use 'virtual'...
template <typename t>
class Foo {
void add(T *t) {
prinf('do some template stuff');
on_added(t);
}
virtual void on_added(T *t) { }
}
struct aaa {}
class Bar : Foo<aaa> {
void on_added(aaa *object) {
printf("on added called on Bar");
}
}
Your on_added function in Foo needs to be virtual.
You have to make the function virtual if you want calls in the base class to use the implementation in the derived class:
template <typename t>
class Foo {
...
virtual void on_added(T *t) { }
};
Note that this is not special to templates, but applies to all classes.
Everyone else has already answered the question. Let me just add that adding virtual functions breaks backward compatibility of the class. So, if this is a class that you control and there are no other dependent classes, then yes you can go ahead and convert the on_added to virtual, if not you need to make sure that the dependent modules are also rebuilt.