如何推导出仿函数的返回值类型?

And*_*rey 15 c++ templates c++11

我想写一个模板函数,它接受2个值和一个函子或一个lambda.该函数使用这些值调用仿函数并返回结果.

template <typename T, typename Fn> 
_ReturnTypeOfPred_ Apply(T x, T y, Fn fn)
  {
  return fn(x, y);
  }
Run Code Online (Sandbox Code Playgroud)

问题:如何定义返回类型Apply等于返回类型Fn?它不一定等于T,在这个仿函数的例子中

template <typename T> 
auto Sum(T x, T y) -> decltype(x+y)
  {
  return x+y;
  }
Run Code Online (Sandbox Code Playgroud)

更新

第一个例子过于简单了.这个应该有用吗?

template <typename TContainer, typename Fn> 
auto Apply(const TContainer& x, const TContainer& y, Fn fn) -> decltype(fn(x.front(), y.front()))
  {
  return fn(x.front(), y.front());
  }
Run Code Online (Sandbox Code Playgroud)

如果我在返回类型中重复return表达式,它会一直有效decltype吗?有更优雅的方式吗?

eca*_*mur 18

你快到了; 只需使用decltype:

template <typename T, typename Fn> 
auto Apply(T x, T y, Fn fn) -> decltype(fn(x, y))
{
  return fn(x, y);
}
Run Code Online (Sandbox Code Playgroud)

你可以使用std::result_of(std :: result_of和decltype之间的区别),但为什么要这么麻烦?

template <typename T, typename Fn> 
typename std::result_of<Fn, T, T>::type Apply(T x, T y, Fn fn)
{
  return fn(x, y);
}
Run Code Online (Sandbox Code Playgroud)

关于后续问题:对于一个功能

auto fn(<args>) -> <return-type> { return <expression>; }
Run Code Online (Sandbox Code Playgroud)

return-typedecltype(<expression>)通常的工作,但很容易出错.例如,考虑:

auto f(char c) -> decltype(std::string() += c) { return std::string() += c; }
Run Code Online (Sandbox Code Playgroud)

decltype将产生std::string &,你的函数将返回一个本地的左值引用!这必须改为:

auto f(char c) -> std::remove_reference<decltype(std::string() += c)>::type {
    return std::string() += c;
}
Run Code Online (Sandbox Code Playgroud)

在其他情况下,<expression>由于例如不可复制的,包含lambda等,可能产生不可返回的值.