Overriding a templated class function - c++

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.

Related

Is there a way to call varying function of member object based on template variable

I have the following code:
class Person {
void func1() {
obj_.function1();
}
void func2() {
obj_.function2();
}
void func3() {
obj_.function3();
}
Object obj_;
};
It's pretty obvious there is a pattern here...
I would like to know if I can call different functions based on template argument.
the functions inside Object are regular member functions.
Is there any way to do something like the following?
class Person {
template <typename Func>
void generic() {
obj_.Func();
}
Object obj_;
};
Another question: Is there a type for function?
I believe it's the key point for it's doable or not.
Thanks
template <auto Func>
void generic() {
(obj_.*Func)();
}
Then foo.generic<&Object::function1>() calls function1.
Prior to c++17:
template <void (Object::*Func)()>
void generic() {
(obj_.*Func)();
}
should work.

Iterate over class inheritances in C++

Assume I have a some classes architecture (the number of the classes is growing up during the development time), that each class inherit from N classes with the same basic interface. What is the best way (if possible) to create a base function (in the base class OR in the derived class) that will iterate over the inheritances?
Target: Avoid developers mistakes and make sure we won't forget to call all the base functions from all of the inheritances & make the code more clear to read and understandable.
Please see edit notes for updated state
Short Example:
class shared_base {
public:
virtual void func() = 0;
}
class base_1 : virtual public shared_base {
public:
void func() override {}
}
class base_2 : virtual public shared_base {
public:
void func() override {}
}
class target : virtual public base_1, virtual public base_2 {
public:
void func() override {
// Instead of:
base_1::func();
base_2::func();
// ... My func() implementation
/*
~~TODO~~
for_each(std::begin(inheritances), std::end(inheritances), [](auto& inheritance) -> void { inheritance::func(); })
~~TODO~~
*/
}
}
More descriptive & practical example:
class base {
public:
virtual void func() = 0;
/*...Some interface (pure virtual) functions...*/
}
class base_core : virtual public base {
public:
void func() override {}
/*...Some base implementations for the rest...*/
protected:
template <typename FuncT>
virtual void iterate_over_base_core_inheritances(FuncT function_to_apply) {
/*~~TODO~~*/
}
}
template <class Decorator = base_core, typename = typename std::enable_if<std::is_base_of<base_core, Decorator>::value>::type>
class core_1 : virtual public Decorator {
public:
void func() override {
// Will iterate (once) over Decorator
/*iterate_over_base_core_inheritances([](core_base*) -> void {
// Implementation
});*/
// Instead of:
Decorator::func();
}
/*More functions implementations*/
}
template <class Decorator = base_core, typename = typename std::enable_if<std::is_base_of<base_core, Decorator>::value>::type>
class core_2 : virtual public core_1<>, virtual public Decorator {
public:
void func() override {
// Will iterate (twice) over core_1 and Decorator
/*iterate_over_base_core_inheritances([](core_base*) -> void {
// Implementation
});*/
// Instead of:
Decorator::func();
core_1::func();
//... Self func() implementation
}
/*More functions implementations*/
protected:
// If it's not possible doing it in the upper hierarchy level is it possible do it here?
template <typename FuncT>
void iterate_over_base_core_inheritances(FuncT function_to_apply) override {
/*~~TODO~~*/
}
}
Some things to know:
I am working on Linux 64x platform (Ubuntu 16.04)- if it's matter for the answers.
The idea behind this code is to create kind of Decorator DP, which will be easy to extend and to understand, and also will enable the developers to use the protected functions/attributes of the base class.
A practical example (for my actual use) can be found in this commit.
Edit:
Thanks to #RaymondChen I got a working solution, with (so far) only one minor issue: Every time I want to use a class that implemented this way, I need to specify the core_base class in it's template arguments list (before- I was using the default type parameter). I am looking for a way to solve this issue.
The current solution:
template <class ...Decorators>
class core_2 : virtual public Decorators... {
public:
static_assert((std::is_base_of<base_core, Decorators>::value && ...), "All decorators must inherit from base_core class.");
void func() override {
(Decorators::func(), ...);
//... Self func() implementation
}
/*More functions implementations*/
}
Creating an instance example:
Current:
std::shared_ptr<base> base = std::make_shared<core_2<core_1<base_core>, core_3<base_core>>>();
Desired:
std::shared_ptr<base> base = std::make_shared<core_2<core_1<>, core_3<>>>();
A practical example (for my actual use) can be found in this commit.
Thanks to #RaymondChen I got really close to my original target with the following solution [See update section at the bottom]:
template <class ...Decorators>
class core_2 : virtual public Decorators... {
public:
static_assert((std::is_base_of<base_core, Decorators>::value && ...), "All decorators must inherit from base_core class.");
void func() override {
(Decorators::func(), ...);
//... Self func() implementation
}
/*More functions implementations*/
}
Explanation:
Using parameters pack we can create a "list" of classes we inherit from, and using folding expression [c++17] we can implement it in just few lines of code.
Pros compare to my original idea:
The object creation line is more clear and logically now:
Before:std::shared_ptr<base> base = std::make_shared<core_2<core_1<core_3<>>>>();
After:std::shared_ptr<base> base = std::make_shared<core_2<core_1<base_core>, core_3<base_core>>>();
Because core_1 & core_3 are independent, but core_2 is using both of them.
No need of new function in the base/derived class, it's just fit within the target line (for example in is_equal function that didn't mention within this post).
Lost functionality:
Template validation of is_base_of (Solved with static_assert & fold expressions).
Default inheritance in case that no inheritance specified is not possible yet (Still trying to solve).
Current:
std::shared_ptr<base> base = std::make_shared<core_2<core_1<base_core>, core_3<base_core>>>();
Desired:
std::shared_ptr<base> base = std::make_shared<core_2<core_1<>, core_3<>>>();
Update
After a lot of research and tries, I came up with the following solution (improved also with C++20 concepts feature):
template <class T>
concept Decorator = std::is_base_of_v<base_core, T>;
class empty_inheritance {};
template<typename Base = base_core, typename ...Decorators>
struct base_if_not_exists {
static constexpr bool value = sizeof...(Decorators);
using type = typename std::conditional<value, empty_inheritance, Base>::type;
};
template <Decorator ...Decorators>
class core_2 : virtual public base_if_not_exists<base_core, Decorators...>::type, virtual public Decorators... {
public:
void func() override {
if constexpr (!base_if_not_exists<base_core, Decorators...>::value) {
base_core::func();
}
(Decorators::func(), ...);
//... Self func() implementation
}
/*More functions implementations*/
}
No functionality lost :)

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

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 ?

C++ Function pointer arguments and classes inheritance automatic cast

First of all sorry if the name of the question is not clear enough. I really have no idea on how to call this problem.
So I have a function pointer inside a class that works like a java callback that I invoke with some parameters like itself that is derived from a parent class like in this example:
class Parent;
using f_Call = void(*)(Parent*);
class Parent
{
public:
void setCallback(f_Call call)
{
mOnCall = call;
}
protected:
f_Call mOnCall = nullptr;
};
class Child1 : Parent
{
public:
void doSomething()
{
// some work..
if (mOnCall)
mOnCall(this);
}
};
void onCallExe(Parent* p)
{
Child1* child = (Child1*)p;
// do some more work...
}
int main()
{
Child1 child;
child.setCallback(onCallExe);
child.doSomething();
}
My question is if does c++ has a way of doing the cast from parent to children automatically in onCallExe so I don't have to do it for every function I call.
Thank you!
Don't use function pointers. Instead, you want std::function<void()> (yes, without arguments) and pass it a lambda with a captured object.
using f_Call = std::function<void()>;
class Parent {
public:
void setCallback(f_Call call) {
mOnCall = call;
}
protected:
f_Call mOnCall;
};
class Child1 : public Parent {
public:
void doSomething() {
// some work..
if (mOnCall)
mOnCall(); // no argument!
}
};
int main() {
Child1 child;
child.setCallback([&child](){ /* do whatever with the child */ });
child.doSomething();
}
If you want, you can hide creation of the lambda in a function template.
template <class Obj, class CB>
void setCallback (Obj& obj, CB cb) {
obj.setCallback([&obj](){cb(obj);});
}
and then pass the global setCallback template any old function with a Child argument.
void onCallExe(Child1& child) {
// do some more work...
}
Child1 child;
setCallback(child, onCallExe);
Curiously recurring template pattern might be an option. However, you'll create separate base classes for each derived one, so you couldn't use them polymorphically – unless you provided a separate, common base. If the recurring template function overwrites a virtual one in the base, you might end up at where you wanted to get:
struct Base
{
virtual ~Base() { }
virtual void f() = 0;
};
template <typename T>
struct Intermediate : Base
{
void f() override
{
if(callback)
callback(static_cast<T*>(this));
}
void setCallback(void(*c)(T*))
{
callback = c;
}
private:
void(*callback)(T*) = nullptr;
};
struct Derived : Intermediate<Derived>
{
};
void g(Derived*) { }
void demo()
{
Derived d;
d.setCallback(g);
d.f();
}
(If you don't need polymorphism, you can skip Base class – then f doesn't have to be virtual either.)
Solely if you wanted to set the callbacks via pointer or reference to Base, you are a bit in trouble, as you cannot have virtual template member functions. You could, though provide a free-standing helper function:
template <typename T>
void setCallback(Base& b, void(*callback)(T*))
{
dynamic_cast<Intermediate<T>&>(b).setCallback(callback);
}
The dynamic cast will throw a std::bad_cast if b is of inappropriate type – unfortunately a rather costly run-time thing, a safe way to let the compiler determine if pointed/referred object is of correct type (usually) is not possible.

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++