C++ 保存函数参数并稍后调用函数的最佳方法是什么?
在C++14中,我希望能够保存函数参数并在以后调用该函数。我的目标是能够做到以下几点:C++ 保存函数参数并稍后调用函数的最佳方法是什么?,c++,templates,stdtuple,C++,Templates,Stdtuple,在C++14中,我希望能够保存函数参数并在以后调用该函数。我的目标是能够做到以下几点: auto delayed_function{ some_callable }; delayed_function( 1, 2, 3 ); // arguments are stored, but some_callable is not called yet delayed_function.call(); // some_callable called with (1,2,3) 主要问题是我需要获
auto delayed_function{ some_callable };
delayed_function( 1, 2, 3 ); // arguments are stored, but some_callable is not called yet
delayed_function.call(); // some_callable called with (1,2,3)
主要问题是我需要获取参数并存储它们。似乎将它们存储在std::tuple中效果最好。问题是元组的确切类型应该是什么。我的想法是,当提供参数时,我需要推断元组的类型(而不是试图从参数推断类型到可调用的元组),因为当提供参数时,它们可能是引用、右值等,我只能从参数类型知道这一点。然而,这意味着,即使我知道可调用的类型,我也不会知道元组的类型,除非在提供参数的模板方法中(在我上面的示例中是运算符())。听起来我需要某种类型的删除。我的参数存储实现当前为:
template <typename Callable>
class arg_tuple
{
public:
template <typename ... Args>
arg_tuple( Args&&... args )
{
using TupleType = decltype( std::make_tuple(std::forward<Args>(args)...) );
args_ =
std::make_unique< typed_arg<TupleType> >(
std::make_tuple(std::forward<Args>(args)...)
);
}
void
invoke( Callable f )
{
args_->invoke( f );
}
private:
template <typename T = void>
struct untyped_arg {
virtual ~untyped_arg() = default;
virtual void invoke( Callable f ) = 0;
};
template <typename T>
struct typed_arg
: public untyped_arg<> {
template <typename Arg>
typed_arg( Arg&& arg )
: value(std::forward<Arg>(arg) ) {}
virtual void
invoke( Callable f )
{
// By moving value, I can only call invoke once, but it potentially saves
// copying, and I can use move-only types in the arg list.
my_apply( f, std::move(value) );
}
T value;
};
std::unique_ptr<untyped_arg<>> args_;
};
模板
类arg_元组
{
公众:
模板
arg_元组(Args&&…Args)
{
使用TupleType=decltype(std::make_tuple(std::forward(args)…);
阿古斯=
std::使_唯一(
std::make_tuple(std::forward(args)…)
);
}
无效的
调用(可调用f)
{
参数->调用(f);
}
私人:
模板
结构非类型化参数{
virtual~untyped_arg()=默认值;
虚空调用(可调用f)=0;
};
模板
结构类型参数
:公共非类型参数{
模板
键入的_arg(arg&&arg)
:值(std::forward(arg)){}
虚空
调用(可调用f)
{
//通过移动值,我只能调用invoke一次,但它可能会节省时间
//复制,并且我可以在arg列表中使用仅移动类型。
我的应用(f,std::move(value));
}
T值;
};
std::唯一的参数;
};
其中“my_apply”本质上是std::apply,但由于我使用的是C++14,所以我必须手动实现它。好消息是这基本上是可行的:
auto f = [](int i) { printf("i+3=%d\n", i+3); };
using Callable = decltype(f);
arg_tuple<Callable> t(20);
t.invoke(f);
autof=[](inti){printf(“i+3=%d\n”,i+3);};
使用Callable=decltype(f);
参数t(20);
t、 调用(f);
然而,让我感到困扰的是,Callable是arg_tuple的一个模板参数。我真的希望它是invoke方法的模板参数,而不是整个类。我这样做的原因是arg_tuple不知道存储的tuple的类型,因此invoke需要一个虚拟函数才能深入到tuple类型已知的位置(typed_arg)。然而,虚拟方法不能有模板参数,所以这就是我被卡住的地方
如果有一种方法可以使Callable成为invoke的模板方法,那么就可以使它成为转发引用,这样我就不必按值接受它。否则,我认为我可能需要为左值、常量左值和右值引用调用多个重载,以防Callable是可变对象
有更好的方法吗?有几种方法 使用未来:
auto value=std::async(std::launch::deferred,delayed_函数,1,2,3);
...
value.get();
或者仅仅使用lambda:
autof=[arg](){返回延迟的_函数(arg,2,3);}
...
f();
有几种方法可以做到这一点
使用未来:
auto value=std::async(std::launch::deferred,delayed_函数,1,2,3);
...
value.get();
或者仅仅使用lambda:
autof=[arg](){返回延迟的_函数(arg,2,3);}
...
f();
我会使用一个lambda,如果需要将它传递给一个std::function
容器来容纳它。我会使用lambda,如果需要将它传递给一个std::function
容器来容纳它。还有一个是轻量级版本std::async
,它总是std::launch::deferred
。还有一个是轻量级版本std::async
,它总是std::launch::deferred
。