Reputation:
I want to be able to perfect forward argument to derived class through base class. The only idea I have is to implement not virtual perfect forwarding function in base class and have virtual functions overloads for lvalues
and rvalues
. Something like this:
Consider:
#include <iostream>
#include <memory>
#include <string>
class base_t
{
public:
virtual ~base_t() = default;
template<typename T>
void perfect_forward(T&& value)
{
process(std::forward<T>(value));
}
protected:
virtual void process(const std::string& value) = 0;
virtual void process(std::string&& value) = 0;
};
class derived_t : public base_t
{
protected:
void process(const std::string& value) override final
{
std::cout << "derived_t::process(const lvalue&)" << std::endl;
}
void process(std::string&& value) override final
{
std::cout << "derived_t::process(rvalue&&)" << std::endl;
}
};
int main(int argc, const char* argv[])
{
const std::string lvalue;
auto rvalue = []() { return std::string(); };
std::unique_ptr<base_t> base(new derived_t);
base->perfect_forward(lvalue);
base->perfect_forward(rvalue());
}
But this has a little meaning, because instead of template perfect_forward
function in base class I can simply provide two overload for virtual process
. How I can avoid code duplicate in derived class for process
method and use std::forward
there through base_t interface?
Upvotes: 1
Views: 852
Reputation: 14420
If you don't want to take the std::string
by value, there is an approach using a mixin class, but it requires changing your class hierachy:
template<class D>
class process_mixin : public base_t {
protected:
void process(std::string const& value) override final {
return ((D*)this)->do_process(value);
}
void process(std::string&& value) override final {
return ((D*)this)->do_process(std::move(value));
}
};
class derived_t : public process_mixin<derived_t> {
protected:
template<typename T>
void do_process(T&& value) {
}
friend process_mixin<derived_t>;
};
process_mixin
only has to be written once. From then on anything that derives from base_t
can instead derive from process_mixin
and you get a perfect forwarding interface.
Upvotes: 3