有人可以解释如何在模板中使用result_of吗?

时间:2014-01-02 19:23:07

标签: c++ templates result-of

我正在尝试创建一个可延迟的调用对象。某些东西(伪代码):

template <class FN>
struct delayable_call
{
    return-type-of-FN call(); // <-- I'd like to use result_of here.

    template<class ArgTypes...>
    delayable_call(FN* pFn, ArgTypes... args);

    FN* fn;
    args-saving-struct;
};

我尝试使用result_of :: type作为返回类型的调用,但是在实例化模板期间会出现错误,因为显然需要单独指定参数类型。

实例化:

int foo(bool, double); // function prototype.

delayable_call<int(bool, double)> delayable_foo(foo, false, 3.14); // instantiation

我读过的关于result_of的错误消息和文档似乎表明还必须指定参数类型。因此,我需要指定result_of<FN>::type而不是result_of<FN(bool, double)>::type。这确实解决了我遇到的编译问题,但打破了模板的普遍性。

那么,当template参数表示函数签名时,如何将result_of与template参数一起使用?

1 个答案:

答案 0 :(得分:1)

template <class FN> struct delayable_call;
template<class R, class...Args> delayable_call<R(Args...)>{
  typedef R(*)(Args...) pFN;

将您的delayable_call替换为专精,您将取代RArgs...。无论如何,您都需要Args...来存储参数。

然而,库强度可延迟调用将最终使用类型擦除。最简单的方法是使用简单的std::function<R()>将lambda推入其中:

int foo(double);
double x = 7;
std::function<int()> delayed_foo = [x]{ return foo(x); }

并按值捕获,除非您真的,实际上是指通过引用捕获它。

您可以通过以下方式推断R

template<typename Fn, typename... Args>
std::function< typename std::result_of<Fn(Args...)>::type()>
make_delayed_call( Fn&& fn, Args&&... args ) {
  return [=]{ return fn(std::move(args)...); }
}

应从可调用对象和参数中推导出R。这通过复制捕获所有内容 - 通过移动捕获需要更多样板或C ++ 14。