#include <iostream>
#include <functional>
using namespace std;
template<typename a, class derived>
class functor
{
public:
virtual ~functor()
{}
template<typename b>
derived map(const std::function<b(a)> &f)
{
// Here you take advantage of the CRTP
return static_cast<derived*>(this)->map(f);
}
};
template<typename l, typename r>
class either : public functor<r, either<l, r>>
{
public:
template<typename b>
either<l, b> map(const std::function<b(r)> &f)
{
cout << "In derived" << endl;
return either<l, b>();
}
};
int main()
{
// pointer to base class points to a derived object
functor<int, either<int, int>> *ff = new either<int, int>();
// map function will call the method of the derived class
ff->map<int>([](int k){ return 1; });
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBhLCBjbGFzcyBkZXJpdmVkPgpjbGFzcyBmdW5jdG9yCnsKcHVibGljOgoJdmlydHVhbCB+ZnVuY3RvcigpCgl7fQoJdGVtcGxhdGU8dHlwZW5hbWUgYj4KCWRlcml2ZWQgbWFwKGNvbnN0IHN0ZDo6ZnVuY3Rpb248YihhKT4gJmYpCgl7CgkJLy8gSGVyZSB5b3UgdGFrZSBhZHZhbnRhZ2Ugb2YgdGhlIENSVFAKCQlyZXR1cm4gc3RhdGljX2Nhc3Q8ZGVyaXZlZCo+KHRoaXMpLT5tYXAoZik7Cgl9Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBsLCB0eXBlbmFtZSByPgpjbGFzcyBlaXRoZXIgOiBwdWJsaWMgZnVuY3RvcjxyLCBlaXRoZXI8bCwgcj4+CnsKcHVibGljOgoJdGVtcGxhdGU8dHlwZW5hbWUgYj4KCWVpdGhlcjxsLCBiPiBtYXAoY29uc3Qgc3RkOjpmdW5jdGlvbjxiKHIpPiAmZikKCXsKCQljb3V0IDw8ICJJbiBkZXJpdmVkIiA8PCBlbmRsOwoJCXJldHVybiAgZWl0aGVyPGwsIGI+KCk7Cgl9Cn07CgppbnQgbWFpbigpIAp7CgkvLyBwb2ludGVyIHRvIGJhc2UgY2xhc3MgcG9pbnRzIHRvIGEgZGVyaXZlZCBvYmplY3QKCWZ1bmN0b3I8aW50LCBlaXRoZXI8aW50LCBpbnQ+PiAqZmYgPSBuZXcgZWl0aGVyPGludCwgaW50PigpOwoJLy8gbWFwIGZ1bmN0aW9uIHdpbGwgY2FsbCB0aGUgbWV0aG9kIG9mIHRoZSBkZXJpdmVkIGNsYXNzCglmZi0+bWFwPGludD4oW10oaW50IGspeyByZXR1cm4gMTsgfSk7CgoJcmV0dXJuIDA7Cn0=