Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
240 views
in Technique[技术] by (71.8m points)

c++ - How to deduce the type of the functor's return value?

I would like to write a template function which accepts 2 values and a functor or a lambda. The function calls the functor with those values and returns the result.

template <typename T, typename Fn> 
_ReturnTypeOfPred_ Apply(T x, T y, Fn fn)
  {
  return fn(x, y);
  }

Question: How can I define the return type of Apply to become equal to the return type of Fn? It is not necessarily equal to T, as in this example of the functor

template <typename T> 
auto Sum(T x, T y) -> decltype(x+y)
  {
  return x+y;
  }

Update

The 1st example was oversimplified. Should this one work?

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());
  }

Would it always work if I repeat return expression in decltype of the return type? Is there a more elegant way?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're nearly there; just use decltype:

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

You could use std::result_of (Difference between std::result_of and decltype) but why bother?

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

Regarding the follow-up question: for a function

auto fn(<args>) -> <return-type> { return <expression>; }

substituting return-type with decltype(<expression>) will usually work, but can be error prone. For example, consider:

auto f(char c) -> decltype(std::string() += c) { return std::string() += c; }

Here decltype will yield std::string & and your function will return an lvalue reference to a local! This would have to be changed to:

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

In other cases, <expression> could yield a value that is not returnable for reason of being e.g. noncopyable, containing a lambda, etc.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...