My problem is that I can't chain methods from Derived
class when I already used Base
class methods. I tried to mix topmost answers from Returning a reference to the derived class from a base class method and CRTP and multilevel inheritance, but the problem is one of them is always returning the same object, the other is returning void
. I want Base
class being able to be inherited by any other class.
[The naive solution to this problem is to make a()
virtual and override it in class Derived
. But what if Base
is inherited by 100 other classes and have 100 other methods to override? This is not scaling good.]
[The other naive solution is to call methods from Derived
class first, then from Base
, but... just no]
So, is it possible to somehow compile the following snippet in native C++? (I am not interested in boost solutions). It would be ideal if main()
's code wouldn't change.
#include <iostream>
#include <type_traits>
template <typename T = void>
class Base
{
public:
T& a();
};
class Derived : public Base<Derived>
{
public:
Derived& b() {std::cout << "b\n"; return *this;}
};
int main()
{
Base base;
base
.a()
;
Derived derived;
derived
.a()
.b()
;
return 0;
}
template <typename T>
T& Base<T>::a()
{
std::cout << "a\n";
if(std::is_same<T, void>::value)
{
return *this;
}
else
{
return static_cast<T&>(*this);
}
}
If only i could write template <typename T = Base> class Base { ...
:)
Not sure if it is what you want, but with C++17 and if constexpr
, you might do:
template <typename T = void>
class Base
{
public:
auto& a()
{
std::cout << "a\n";
if constexpr (std::is_same_v<T, void>) {
return *this;
} else {
return static_cast<T&>(*this);
}
}
};
Before, you might use specialization.