我有一个抽象类 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
的参数编号未知,因此必须使用参数包。答案 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 )... ) };
}