【发布时间】:2016-03-18 08:24:37
【问题描述】:
我希望能够通过基类完善前向参数到派生类。我唯一的想法是在基类中实现非虚拟完美转发功能,并为lvalues 和rvalues 提供虚拟函数重载。像这样的:
考虑:
#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 提供两个重载,而不是基类中的模板perfect_forward 函数。如何避免process 方法的派生类中的代码重复,并通过base_t 接口使用std::forward?
【问题讨论】:
-
如果您想要动态多态性,您将需要在某些时候进行虚拟调用,并且函数模板当然不能是虚拟的。你可以在
derived_t中有一个模板化的函数,它可以从派生类中的两个重载中调用。 -
似乎在基类中为虚函数提供两个重载是最简单的方法:(
-
你可以使用
virtual void process(std::string value)。 -
简单,是的,但正如 Effective Modern C++ 在第 41 条中向我们学习的那样,这并不总是最佳选择。
-
“不总是最佳选择”是否意味着“从不”?你似乎不假思索地放弃了这个建议。
标签: c++ c++11 polymorphism perfect-forwarding