Ensure that class derived from parent CRTP class implements function - c++

Brief:
I want to make sure a derived class implements a member function required by a function within the parent CRTP class.
Detail:
I have some code like this
class Base
{
public:
class Params
{
public:
virtual ~Params() {}
};
virtual void myFunc( Params& p ) = 0;
};
template< typename T >
class CRTP : public Base
{
public:
virtual void myFunc( Base::Params& p ) override
{
typename T::Params& typedParams = dynamic_cast<typename T::Params&>( p );
static_cast<T*>( this )->myFunc( typeParams );
}
};
class Imp : public CRTP<Imp>
{
public:
class Params : public CRTP<Imp>::Params
{
public:
virtual ~Params() {}
int x, y, z;
};
virtual void myFunc( Imp::Params& p );
};
The intention is that I can have multiple Imp child classes all doing different things in myFunc and accepting their own required parameters. The interface provided by Base is then utilized by higher level functions that only need to have a pointer/reference of type Base::Params and Base. My problem is making sure that any Imp provides a specialized myFunc. To avoid infinite recursion Imp must implement myFunc.
My first try was adding a pure virtual function to CRTP
virtual void myFunc( typename T::Params& p ) = 0;
but that doesn't work as Imp hasn't been fully defined when CRTP is being defined. This question uses a static_assert which made me think of doing the same with the static_assert within CRTP::myFunc. Except I'm not sure what should be the expression in the static assertion for a non-static function.
Can I use a static_assert for what I need?
Is that the best/cleanest way to ensure the derived class has the needed function?
Have I got carried away with my class design and there is a better way of doing things?
Thanks.

Why not just use a different name for the function? Then you will have a compilation error for each derivation of CRTP class without and implementation. Consider this:
class Base
{
public:
class Params
{
public:
virtual ~Params() {}
};
virtual void myFunc( Params& p ) = 0;
};
template< typename T >
class CRTP : public Base
{
public:
virtual void myFunc( Base::Params& p ) final override
{
typename T::Params& typedParams = dynamic_cast<typename T::Params&>( p );
static_cast<const T*>( this )->myFuncImp( typedParams );
}
};
class Imp : public CRTP<Imp>
{
public:
class Params : public CRTP<Imp>::Params
{
public:
virtual ~Params() {}
int x, y, z;
};
};
int main(int argc, char** argv)
{
Imp imp;
}
Compilation fails since there is no myFuncImp provided by Imp.

You may break dynamic polymorphism and switch to static polymorphism:
#include <iostream>
#include <type_traits>
class Base
{
public:
class Params
{
public:
virtual ~Params() {}
};
virtual ~Base() {}
virtual void myFunc(Params& p) = 0;
};
namespace Detail {
// Helper for the static assertion
// Omit this if "‘void CRTP<T>::myFunc(Base::Params&) [with T = Imp]’ is private" is good enough
struct is_MyFunc_callable_implementation
{
template<typename Object, typename Params>
static decltype(std::declval<Object>().myFunc(std::declval<Params&>()), std::true_type())
test(int);
template<typename Object, typename Params>
static std::false_type
test(...);
};
template<typename Object, typename... A>
using is_MyFunc_callable = decltype(is_MyFunc_callable_implementation::test<Object, A...>(0));
// Helper function to break recursion
template<typename Object, typename Params>
inline void invokeMyFunc(Object& object, Params& params) {
static_assert(is_MyFunc_callable<Object, Params>::value, "The derived class is missing 'MyFunc'");
object.myFunc(params);
}
} // namespace Detail
template<typename T>
class CRTP: public Base
{
private:
// Make this final!
virtual void myFunc(Base::Params& p) override final
{
static_assert(std::is_base_of<Base, T>::value, "T must derive from CRTP");
typename T::Params& typeParams = dynamic_cast<typename T::Params&>(p);
Detail::invokeMyFunc(static_cast<T&>(*this), typeParams);
}
};
class Imp: public CRTP<Imp>
{
public:
class Params: public CRTP<Imp>::Params
{
public:
int x = 1;
int y = 2;
int z = 3;
};
// Without this function:
// error: static assertion failed: The derived class is missing 'MyFunc'
// error: ‘void CRTP<T>::myFunc(Base::Params&) [with T = Imp]’ is private
#if 0
void myFunc(Params& p) {
std::cout << p.x << p.y << p.z << '\n';
}
#endif
};
int main()
{
Imp imp;
Base* base = &imp;
Imp::Params params;
base->myFunc(params);
}
However, my opinion is: The base class design is a failure and the code above is just a work around.

The idea of using a different name for the member of derived classes (as in Rudolfs Bundulis answer) is good. However, I would make this a protected method so that users are not tempted to try using it.
Also, using Derived::Params in the CRTP base raises additional complications (since Derived=Imp is not fully declared at point of its use in CRTP<Imp>), so best keep Base::Params as the function parameter throughout.
struct Base // public user interface
{
struct Params { virtual ~Params() {} };
virtual void myFunc( Params& ) = 0;
};
namespace details { // deter clients from direct access
template< typename Derived >
struct CRTP : Base
{
virtual void myFunc( Params& p ) final // cannot be overridden
{
static_cast<Derived*>( this )->myFuncImp(p);
}
};
class Imp : public CRTP<Imp>
{
struct Params : CRTP<Imp>::Params { int x, y, z; };
void myFuncImpDetails( Params* );
protected: // protected from clients
void myFuncImp( Base::Params& p )
{
auto pars=dynamic_cast<Params*>(&p);
if(pars)
myFuncImpDetails(pars);
else
throw std::runtime_error("invalid parameter type provided to Imp::myFunc()");
}
};
} // namespace details

Related

C++ - Pushing variadic template class object into vector

class Base
{
public:
virtual void foo() = 0;
};
class A : public Base
{
public:
void foo() override { std::cout << "A\n"; }
};
class B : public Base
{
public:
void foo() override { std::cout << "B\n"; }
};
class Registry
{
public:
static Registry& instance()
{
static Registry s_instance;
return s_instance;
}
void register_foo(Base* foo)
{
m_vec.emplace_back(foo);
}
private:
std::vector<Base*> m_vec;
};
template<typename ... T>
class Foo : public T...
{
public:
Foo()
{
Registry::instance().register_foo(this);
}
void test() { (T::foo(), ...); }
};
int main()
{
auto f1 = std::make_unique<Foo<A, B>>();
auto f2 = std::make_unique<Foo<A>>();
f1->test();
f2->test();
}
As you can see I have a Base class, class A and class B.
A and B inherit from Base.
Class Foo is a template class, which is with a variadic template.
The idea is to be able to pass class A and class B into Foo.
Then this Foo is registered in the Registry class / pushed into a vector.
The problem is the following - as you can see I can have both Foo<A> and Foo<A, B>, or Foo<B, A>.
How can I have such a vector which can accept all possible types of Foo?
How about a simple common base class?
class FooBase {
public:
virtual ~FooBase() {}
virtual void test() = 0;
};
template<typename... T>
class Foo : public FooBase, public T...
{
public:
Foo() { }
void test() override { (T::foo(), ...); }
};
int main()
{
auto f1 = std::make_unique<Foo<A, B>>();
auto f2 = std::make_unique<Foo<A>>();
std::vector<std::unique_ptr<FooBase>> foos;
foos.push_back(std::move(f1));
foos.push_back(std::move(f2));
}
A std::vector holds one type of objects. You cannot put objects of different types into the same vector (and objects created from a template with different template arguments are different types).
One option (I'd not recommend it) is having a vector that holds instances of std::any) - works, but cumbersome and inefficient to work with. Another option is a vector of pointers to a common base class and taking advantage of polymorphism. A third option is simply having sepperate vectors for each type of object.

Can a base class be declared in C++ such that classes derived from it can only be created via a creation function?

in something like the following
class Base
{
protected:
Base()
{}
public:
virtual void initialize()
{}
template<typename D, typename... Ts>
static std::shared_ptr<D> create(Ts... args)
{
auto d = std::shared_ptr<D>(new D(args...));
d->initialize();
return d;
}
};
class Derived : public Base
{
private:
int value_;
protected:
public:
Derived(int v) : value_(v)
{}
void initialize() override
{
//Do something with value_
}
};
int main()
{
auto derived = Base::create<Derived>(42);
// etc.
return 0;
}
The above works as expected but if Base was part of a class library that the user of the library was extending by implementing Derived, there is nothing preventing the user of the library from creating a Derived via its public constructor and thus initialize won't be called.
In such a library/library user scenario how could one enforce usage of something like Base::create(...) for Derived class creation?
For example, if Base::Base() is made private rather than protected the code won't compile because Derived::Derived() wont be able to access it.
This solution is a bit finicky, but I think it covers all bases:
class Base
{
protected:
// Token is only visible to Derived, and only constructible by Base
class token {
friend Base;
token() {};
};
// Constructing Base requires a token
Base(token)
{}
public:
// bla
template<typename D, typename... Ts>
static std::shared_ptr<D> create(Ts... args)
{
auto d = std::shared_ptr<D>(new D({}, args...));
// Token is created here ^^
// bla
}
};
class Derived : public Base
{
// bla
public:
// Derived receives and forwards the token to Base
// The implicit copy constructor is accessible
Derived(token t, int v) : Base(t), value_(v)
{}
// bla
};
Thus, no one can write Derived d(Base::token{}, 42) because token is inaccessible. Derived itself can name token and pass one around, but cannot create one: only Base's create function can.
If your aim is just to make sure that initialize function is called by derived classes make it pure virtual.
I would suggest to use Non-Virtual Interface(NVI) idiom.
In this way library users are enforced to implement doInitialize function in derived classes.
class Base
{
protected:
Base()
{
}
public:
void initialize()
{
doInitialize();
}
template<typename D, typename... Ts>
static std::shared_ptr<D> create(Ts... args)
{
auto d = std::shared_ptr<D>(new D(args...));
d->initialize();
return d;
}
virtual ~Base() = default;
protected:
virtual void doInitialize() = 0;
};
class Derived : public Base
{
private:
int value_;
public:
Derived(int v) : value_(v)
{}
private:
void doInitialize() override
{
//Do something with value_
}
};
int main()
{
auto derived = Base::create<Derived>(42);
return 0;
}

Diamond inheritance - call all parent functions

Say I've got the following (pseudo-)code:
class base{
public:
virtual void callMe() = 0;
virtual void doRender() = 0;
}
class a : public base{
public:
virtual void callMe(){/*doA*/} override;
}
class b : public base{
public:
virtual void callMe(){/*doB*/} override;
}
class myClass : public base, public a, public b{
public:
virtual void doRender(){
this->a::callMe();
this->b::callMe();
} override;
}
Would there be a way to write this differently? Something like:
class myClass : public base, public a, public b{
public:
virtual void doRender(){
this->allSupers::callMe();
} override;
}
My goal with this would be to have a base class that can be extended to have different "features", all of which have to be executed on doRender.
I know I could of course keep track of these functions by means of a function pointer list in base, in which the subclasses put their own functions when constructed, but I'd like to avoid that. Having to iterate over these functions still gives me at least three lines of code in my final doRender. (Or one long unreadable line.)
I'm open for suggestions using templates.
Depending on you actual problem at hand, you might be able to use the mixin-style. Essentially you can have each class call the next callMe at the end (or begining) of their own callMe. One benefit is that callMe does not need to be a virtual function. Here is a minimal example (online):
#include <iostream>
class base
{
public:
void callMe() {}; // Empty base case
virtual void doRender() = 0;
};
template <class super>
class a : public super
{
public:
void callMe()
{
std::cout << "doA" << '\n';
super::callMe(); // Call the next
};
};
template <class super>
class b : public super
{
public:
void callMe()
{
std::cout << "doB" << '\n';
super::callMe(); // Call the next
};
};
template <class super>
class myClass_t : public super
{
public:
void doRender()
{
super::callMe();
};
};
using myClass = myClass_t<a<b<base> > >; // Defining the order of evaluation;
int main()
{
myClass m;
m.doRender();
}
With variadic template, you may do:
template <typename ... Ts>
class myClassTs : public base, public Ts...
{
public:
virtual void doRender(){
int dummy[] = {0, (Ts::callMe(), void(), 0)...};
static_cast<void>(dummy); // Silent warning for unused variable
} override;
}
using myClass = myClassTs<a, b>;
And in C++17, it would be
template <typename ... Ts>
class myClassTs : public base, public Ts...
{
public:
virtual void doRender(){
(static_cast<void>(Ts::callMe()), ...);
} override;
}

Template a virtual method from base class instead of use overloading

I got strange code and have to extend it. But instead of copy paste many many times i decided to create a template. But get caught by a terrible rock.
Here is an example code:
template<typename T>
class anyClass {};
template<typename T>
class Outer : public anyClass<T>
{
public:
using value_t = T;
class Inner
{
virtual void foo(value_t);
};
};
class specializer : protected Outer::Inner
{
virtual void foo(int) override {}
}
I have to extend virtual void foo(value_t) in specializer.
Example:
class specializer : protected Outer::Inner
{
virtual void foo(int) override {}
virtual void foo(float) override {}
virtual void foo(string) override {}
virtual void foo(bar) override {}
// And so on...
}
Question 1: Why works the example, although class specializer : protected Outer::Inner miss a param?
All overloadings do nearly the same. I created already the function.
template<typename anyType>
void meow( anyType )
{
/***/
}
My problem is here:
virtual void foo(anytype value) //<< replace anytype with what?
{
meow<anytype>( value );
}
I need the type Outer::value_T but i don't know how to get it.
Question 2: How can i use meow by calling foo ?
Feel free to ask for more information.
UPDATE
I looked again in the origin code and realised, that i've overlooked an important using/typedef.
The working code looks like:
class specializer : protected Outer<int, float, string, bar>::Inner //Yes a variadic-template
{
virtual void foo(int) override {}
virtual void foo(float) override {}
virtual void foo(string) override {}
virtual void foo(bar) override {}
// And so on...
}
So Question 1 is solved.
Why works the example, although class specializer : protected Outer::Inner miss a param?
The example does not work. It does not work because Outer is not a type. Also, you override multiple overloads of foo even though inner has only one foo. There are several syntax errors too. If it appears to work, then the compiler is doing something non-standard.
About your second question:
virtual void foo(anytype value) //<< replace anytype with what?
You replace it with the type whose overload you intend to override. For example, if you intend to override foo(int), then replace anytype with int.
Question 2: How can i use meow by calling foo ?
Simply call meow in foo.
You would have to make specializer a template class.
#include <iostream>
template<typename T> void meow(T x)
{
std::cout << x << std::endl;
}
template<typename T>
class anyClass {};
template<typename T>
class Outer : public anyClass<T>
{
public:
using value_t = T;
class Inner
{
virtual void foo(Outer<T>::value_t);
};
};
template<typename T>
class specializer : protected Outer<T>::Inner
{
virtual void foo(T x) override
{
meow(x);
}
};
I wonder how this would help you to change the behavior in Outer or anyClass because you have not shown code which shows where and how Inner is actually used. Without that, it's just guessing.
I have the feeling that what you are actually trying to achieve is to pass a function (or Strategy?) to you Outer class, represented by Inner in your code. That would be better done by passing it as a template argument.
template<typename T>
class anyClass {};
template<typename T, typename Inner = meow<T>>
class Outer : public anyClass<T>
{
public:
using value_t = T;
// somewhere in your code
Inner i;
i.meow( any_value );
};
You can also pass a std::function to the constructor.
template
class anyClass {};
template<typename T>
class Outer : public anyClass<T>
{
public:
using value_t = T;
Outer( std::function<void (value_t)> inner);
// somewhere in your code
i.meow( any_value );
std::function<void (value_t)> i;
};
Originally I simplyfied a little bit to much.
Here is the compileable example of my problem: http://ideone.com/9U7J1a
I removed all unconducive code. I know the design is horrible but i have no influence on it.
class bar {};
class string {};
template<typename _T>
class ModelContainer
{
public:
using value_type = _T;
class Delegate {
public:
virtual void foo( value_type value);
};
};
template< typename... _Ts >
class ModelManager__AbstractBase : protected ModelContainer< _Ts >...
{
public:
class Delegate : public ModelContainer< _Ts >::Delegate... {
public:
virtual ~Delegate( ) = default;
};
};
using ModelManager__Base = ModelManager__AbstractBase<
int,
float,
string,
bar
>;
class ModelManager : public ModelManager__Base {
/* Some functions */
};
class spezializer : ModelManager::Delegate
{
public:
virtual ~spezializer() = default;
//Uncommend to see my error
// virtual void foo( value_type value) override // << value_type unknown
// {/* Calling everytime the same method, no matter which value_type*/}
};

How to enable_shared_from_this of both parent and derived

I have simple base and derived class that I want both have shared_from_this().
This simple solution:
class foo : public enable_shared_from_this<foo> {
void foo_do_it()
{
cout<<"foo::do_it\n";
}
public:
virtual function<void()> get_callback()
{
return boost::bind(&foo::foo_do_it,shared_from_this());
}
virtual ~foo() {};
};
class bar1 : public foo , public enable_shared_from_this<bar1> {
using enable_shared_from_this<bar1>::shared_from_this;
void bar1_do_it()
{
cout<<"foo::do_it\n";
}
public:
virtual function<void()> get_callback()
{
return boost::bind(&bar1::bar1_do_it,shared_from_this());
}
};
Causes exception tr1::bad_weak_ptr in following code:
shared_ptr<foo> ptr(shared_ptr<foo>(new bar1));
function<void()> f=ptr->get_callback();
f();
So after "googling" I have found following solution:
class bar2 : public foo {
void bar2_do_it()
{
cout<<"foo::do_it\n";
}
shared_ptr<bar2> shared_from_this()
{
return boost::static_pointer_cast<bar2>(foo::shared_from_this());
}
public:
virtual function<void()> get_callback()
{
return boost::bind(&bar2::bar2_do_it,shared_from_this());
}
};
And now it works.
Is there any better and more convinient and correct way to enable_shared_from_this for both parent and child?
Thanks
The OP solution can be made more convenient by defining the following on the base class.
protected:
template <typename Derived>
std::shared_ptr<Derived> shared_from_base()
{
return std::static_pointer_cast<Derived>(shared_from_this());
}
This can be made more convenient by placing it in a base class (for reuse).
#include <memory>
template <class Base>
class enable_shared_from_base
: public std::enable_shared_from_this<Base>
{
protected:
template <class Derived>
std::shared_ptr<Derived> shared_from_base()
{
return std::static_pointer_cast<Derived>(shared_from_this());
}
};
and then deriving from it as follows.
#include <functional>
#include <iostream>
class foo : public enable_shared_from_base<foo> {
void foo_do_it()
{
std::cout << "foo::do_it\n";
}
public:
virtual std::function<void()> get_callback()
{
return std::bind(&foo::foo_do_it, shared_from_base<foo>());
}
};
class bar1 : public foo {
void bar1_do_it()
{
std::cout << "bar1::do_it\n";
}
public:
virtual std::function<void()> get_callback() override
{
return std::bind(&bar1::bar1_do_it, shared_from_base<bar1>());
}
};
Sorry, but there isn't.
The problem is that shared_ptr<foo> and shared_ptr<bar1> are different types. I don't understand everything that's going on under the hood, but I think that when the constructor returns and is assigned to a shared_ptr<foo>, the internal weak_ptr<bar1> sees that nothing is pointing to it (because only a shared_ptr<bar1> would increment the counter) and resets itself. When you call bar1::shared_from_this in get_callback, you get the exception because the internal weak_ptr isn't pointing to anything.
Essentially, enable_shared_from_this only seems to work transparently from a single class in a hierarchy. If you try implementing it manually, the problem should become obvious.
A similar solution to #evoskuil that reduces boilerplate in derived classes should you want to implement a shared_from_this() function, resulting in the following code at the point of use in the class:
auto shared_from_this() {
return shared_from(this);
}
This uses 'shim' functions outside of the class. By doing it that way it also provides a clean way to do this for classes who's interface can't be modified but derive from enable_shared_from_this - e.g.
auto shared_that = shared_from(that);
Note: Use of auto for return types here will depend upon the age of your compiler.
Shim functions that could be placed in a library header:
template <typename Base>
inline std::shared_ptr<Base>
shared_from_base(std::enable_shared_from_this<Base>* base)
{
return base->shared_from_this();
}
template <typename Base>
inline std::shared_ptr<const Base>
shared_from_base(std::enable_shared_from_this<Base> const* base)
{
return base->shared_from_this();
}
template <typename That>
inline std::shared_ptr<That>
shared_from(That* that)
{
return std::static_pointer_cast<That>(shared_from_base(that));
}
The above code relies on the fact that the type passed to shared_from(...) inherits from std::enable_shared_from_this<Base> at some point in its ancestry.
Calling shared_from_base will figure out what type that ultimately was. Since we know that That inherits from Base, a static downcast can be made.
Probably there are some pathological corner cases with classes having type conversion operators.. but that's unlikely to occur in code not designed to break this.
Example:
struct base : public std::enable_shared_from_this<base> {};
struct derived : public base
{
auto shared_from_this() {
return shared_from(this);
}
// Can also provide a version for const:
auto shared_from_this() const {
return shared_from(this);
}
// Note that it is also possible to use shared_from(...) from
// outside the class, e.g.
// auto sp = shared_from(that);
};
template <typename X>
struct derived_x : public derived
{
auto shared_from_this() {
return shared_from(this);
}
};
Compilation test:
int main()
{
auto pbase = std::make_shared<base>();
auto pderived = std::make_shared<derived>();
auto pderived_x = std::make_shared<derived_x<int> >();
auto const& const_pderived = *pderived;
const_pderived.shared_from_this();
std::shared_ptr<base> test1 = pbase->shared_from_this();
std::shared_ptr<derived> test2 = pderived->shared_from_this();
std::shared_ptr<derived_x<int> > test3 = pderived_x->shared_from_this();
return 0;
}
https://onlinegdb.com/SJWM5CYIG
Prior solution that I posted, kept to make the comments still make sense - this placed the functions in the base class which had some problems - particularly non-uniformity between the required implementation for 'normal' classes and template classes.
Additionally the implementation in the base class would need to be repeated for new class hierarchies which is not all that DRY.
Furthermore the base class function suffered from the possibility of misuse by supplying a base class pointer from a different object. The newer scheme above avoids this entirely and the runtime assert(...) check goes.
Old implementation:
#include <cassert>
#include <memory>
class base : public std::enable_shared_from_this<base>
{
protected:
template <typename T>
std::shared_ptr<T> shared_from(T* derived) {
assert(this == derived);
return std::static_pointer_cast<T>(shared_from_this());
}
};
class derived : public base
{
public:
auto shared_from_this() {
return shared_from(this);
}
};
template <typename X>
class derived_x : public derived
{
public:
auto shared_from_this() {
return this->template shared_from(this);
}
};
int main()
{
auto pbase = std::make_shared<base>();
auto pderived = std::make_shared<derived>();
auto pderived_x = std::make_shared<derived_x<int> >();
std::shared_ptr<base> test1 = pbase->shared_from_this();
std::shared_ptr<derived> test2 = pderived->shared_from_this();
std::shared_ptr<derived_x<int> > test3 = pderived_x->shared_from_this();
return 0;
}
Quite easy; inherit public shared_from_this only in your base class. Implement an accessor in your derived class that casts to the appropriate type;
std::shared_ptr<Derived> shared()
{
return std::dynamic_pointer_cast<Derived>(Base::shared_from_this());
}
With c++23 deducing this, things become much easier. https://godbolt.org/z/j499WK58Y
#include <memory>
#include <iostream>
#include <functional>
using namespace std;
struct new_enable_shared_from_this :
public std::enable_shared_from_this<new_enable_shared_from_this> {
template <typename Self>
auto new_shared_from_this(this Self& self) {
return std::static_pointer_cast<Self>(self.shared_from_this());
}
};
class foo : public new_enable_shared_from_this {
void foo_do_it()
{
cout<<"foo::do_it\n";
}
public:
virtual function<void()> get_callback()
{
return bind(&foo::foo_do_it,new_shared_from_this());
}
virtual ~foo() {};
};
class bar1 : public foo {
void bar1_do_it()
{
cout<<"foo::do_it\n";
}
public:
virtual function<void()> get_callback()
{
return bind(&bar1::bar1_do_it,new_shared_from_this());
}
};
int main() {
auto pf = std::make_shared<foo>();
pf->get_callback()();
auto pb = std::make_shared<bar1>();
pb->get_callback()();
}
This is the previous answer:
Well, I don't like virtual function. Virtual function is just for type erasing, but we don't need type erasing all the time. So, provide a mechanism for type erasing is enough. Here is an example that don't use virtual function:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
template<typename derived>
class foo_imp {
void foo_do_it()
{
cout<<"foo::do_it\n";
}
public:
function<void()> get_callback()
{
auto&& d = static_cast<derived&>(*this);
return bind(&foo_imp::foo_do_it, d.shared_from_this());
}
};
template<typename derived>
class bar_imp {
void bar_do_it()
{
cout<<"bar::do_it\n";
}
public:
function<void()> get_callback()
{
auto&& d = static_cast<derived&>(*this);
return bind(&bar_imp::bar_do_it, d.shared_from_this());
}
};
struct foo : public foo_imp<foo>, public enable_shared_from_this<foo> {};
struct bar : public bar_imp<bar>, public enable_shared_from_this<bar> {};
struct v_foo {
virtual function<void()> get_callback() = 0;
};
template <typename T>
std::shared_ptr<v_foo> convert(const std::shared_ptr<T>& st) {
struct _ : public v_foo {
_(const std::shared_ptr<T>& st) : _st{st} {}
function<void()> get_callback() override {
return _st->get_callback();
}
std::shared_ptr<T> _st;
};
return std::make_shared<_>(st);
}
int main() {
auto sf = make_shared<bar>();
sf->get_callback()();
auto svf = convert(sf);
svf->get_callback()();
auto sb = make_shared<foo>();
sb->get_callback()();
auto svb = convert(sb);
svb->get_callback()();
}
#include <memory>
template<class T>
class Base : public std::enable_shared_from_this<T> {
};
class Derived : public Base<Derived> {
std::shared_ptr<Derived> getDerived() { return shared_from_this(); }
};