当你不知道传递给覆盖函数的参数时,在基类中创建一个overriden方法?

时间:2016-08-31 15:21:37

标签: c++ inheritance polymorphism override

我有一个抽象类 A ,它是其他类的基础,假设 B C

B C 应具有void类型handle_input方法,但参数编号和类型可能与 B <不同/ strong>到 C

我还有一个将指针作为参数 A 的函数 - 多态地说,可以是 A ,< strong> B C - 并调用方法handle_input

定义A::handle_input时出现问题,因为传递给B::handle_input的参数可能与传递给C::handle_input的参数不同。

这让我在课堂上创建了 A 之类的东西:

/* base class */
class A {
    template <class... FUNCTION_ARGS>
    virtual void handle_input(FUNCTION_ARGS&&...) = 0;
};

但是出现错误是因为模板是在编译时计算的,而虚拟是在运行时使用的。

我也做了

class A {
    template <class... FUNCTION_ARGS>
    using input_handler = function<void(FUNCTION_ARGS&&...)>;

    template <class... FUNCTION_ARGS>
    input_handler<FUNCTION_ARGS...> handle_input;
};

但结果或多或少与预期相同。

我想我的问题是“当你不知道传递给潜在的多个重写函数的参数时,如何在基类中创建一个overriden方法?”

备注(如果我错了,请纠正我):

  • handle_input是动态多态的,所以它必须是虚拟的。
  • handle_input的参数编号未知,因此必须使用参数包。

1 个答案:

答案 0 :(得分:2)

我提供了一个非常出色的实现,并在此处作了解释:

https://codereview.stackexchange.com/q/140510/88422

为了规避NathanOliver所说的话,你可以使用闭包。他们将存储他们的参数,你可以多态地调用它们。

免责声明:这是展示该技术的非常准确的实现方式。

$result

样本用法:

template<class F, class... Args>
auto make_closure( F&& f, Args&&... args ) noexcept
{
    return [=] { return f( args... ); };
}

struct fn_base
{
    virtual ~fn_base() = default;
    virtual void invoke() = 0;
};

template<class T, class... Args>
struct fn : public fn_base
{
    using closure_t = decltype( make_closure( std::declval<T>(), std::declval<Args>()... ) );
    closure_t closure_;

    fn( closure_t&& closure ) : closure_{ std::move( closure ) } {}

    void invoke() override
    {
        closure_();
    }
};

template<class F, class... Args>
auto make_fn( F&& f, Args&&... args )
{
    return fn<F, Args...>{ make_closure( std::forward<F>( f ), std::forward<Args>( args )... ) };
}