通过base完美转发class

perfect forwarding through base class

我希望能够通过基础 class 完善派生 class 的正向论证。我唯一的想法是在基 class 中实现非虚拟完美转发功能,并为 lvaluesrvalues 重载虚拟功能。像这样:

考虑:

#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());
}

但这有一点意义,因为我可以简单地为虚拟 process 提供两个重载,而不是基础 class 中的模板 perfect_forward 函数。如何避免在 process 方法的派生 class 中重复代码并通过 base_t 接口使用 std::forward

如果您不想按值获取 std::string,可以使用 mixin class 的方法,但它需要更改您的 class 层次结构:

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只需要写一次。从那时起,从 base_t 派生的任何东西都可以改为从 process_mixin 派生,你将获得一个完美的转发接口。