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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…