Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 保存函数参数并稍后调用函数的最佳方法是什么?_C++_Templates_Stdtuple - Fatal编程技术网

C++ 保存函数参数并稍后调用函数的最佳方法是什么?

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) 主要问题是我需要获

在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)
主要问题是我需要获取参数并存储它们。似乎将它们存储在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