And*_*rey 13 c++ lambda templates c++11
这个问题是如何推断出仿函数的返回值类型的后续行动? 我正在以更抽象的方式重新制定它.
给定模板函数的伪代码
template <typename Arg, typename Fn>
auto ComputeSomething(Arg arg, Fn fn) -> decltype(<decl-expr>)
{
// do something
// ............
return fn(<ret-expr>)
}
Run Code Online (Sandbox Code Playgroud)
where <ret-expr>是一个涉及的任意表达式,arg我将使用什么<decl-expr>来设置返回类型ComputeSomething等于函子的返回类型.
仿函数可以是类,lambda或函数指针.
到目前为止我发现的部分解决方案.
(a)ecatmur所做的相关问题的答案.从本质上讲,它重复了返回语句<decl-expr>.问题:它容易出错,如果包含局部变量则无法工作.
(b)它仅适用于函数指针
template <typename Arg, typename Ret>
Ret ComputeSomething(Arg arg, Ret(*fn)(Arg))
Run Code Online (Sandbox Code Playgroud)
(c)它假定仿函数的参数是类型的Arg(一般可能不成立)并且需要Arg默认构造
template <typename Arg, typename Fn>
auto ComputeSomething(Arg arg, Fn fn) -> decltype(fn(Arg())
Run Code Online (Sandbox Code Playgroud)
(d)使用std::declval哪个应该解除默认构造限制,如在模板中推导函数的返回类型所建议的那样.谁有人解释它是如何工作的?
template <typename Arg, typename Fn>
auto ComputeSomething(Arg arg, Fn fn) -> decltype(fn(std::declval<Arg>())
Run Code Online (Sandbox Code Playgroud)
Ant*_*ams 11
std::declval是一个仅声明(未定义)的函数模板.因此,它可以仅在未计算的上下文中使用,如参数sizeof和decltype.声明它返回指定类型的右值.这允许您使用它为decltype表达式中的函数调用生成伪参数.
例如
typedef decltype(fn(std::declval<Arg>())) t;
Run Code Online (Sandbox Code Playgroud)
声明t为fn使用rvalue类型调用的结果的类型Arg.这类似于你的case(c)(fn(Arg())),但它不需要任何东西Arg,所以它适用于没有默认构造函数的类型.
如果返回表达式使用类型的局部变量foo,那么decltype(fn(std::declval<foo>()))无论您如何构造a,都可以再次使用foo.
如果您需要左值,例如命名对象或左值引用,则可以使用std::declval<foo&>().这允许您处理类型取决于您是否具有左值或右值的情况.
这是我自己的解决方案,我能得到的最好的解决方案
template <typename Arg, typename Fn>
typename std::result_of<Fn(Arg)>::type ComputeSomething(Arg arg, Fn fn)
Run Code Online (Sandbox Code Playgroud)