我想推断出作为模板参数的函数的返回类型。请考虑以下代码:
#include <type_traits>
struct Result {};
Result foo() { return Result{}; }
template<typename Factory>
void check(Factory) {
using ActualResult = typename std::result_of<Factory()>::type;
static_assert(std::is_same<Result, ActualResult>::value, "");
}
int main() {
check(foo);
}
这可以按预期工作。但是,如果我将check()
的参数更改为const Factory&
,则它不会编译。 gcc的错误是:
prog.cc: In instantiation of 'void check(const Factory&) [with Factory = Result()]':
prog.cc:14:14: required from here
prog.cc:9:66: error: function returning a function
using ActualResult = typename std::result_of<Factory()>::type;
^
prog.cc:10:65: error: function returning a function
static_assert(std::is_same<Result, ActualResult>::value, "");
^
这里有什么问题?我怎样才能使它发挥作用?
答案 0 :(得分:2)
函数(就像数组一样)既不能作为prvalue参数传递,也不能作为prvalues返回。
因此,带有prvalue参数的template <typename Factory> void check(Factory)
会导致foo
衰减到函数指针,而check(foo)
会导致Factory
推断为{Result (*)()
1}}。最后,result_of<Factory()>
给出了调用可调用类型的结果,该类型是没有参数的函数指针。
当您将check
更改为check(const Factory&)
时,该函数采用左值,因此没有衰减,Factory
被推断为函数类型Result()
。这不是允许传递给result_of
*的类型,它需要可调用类型或对函数的引用。也就是说,在这种情况下你应该使用result_of<Factory&()>
。
*)在C ++ 11中。 result_of
的规则可能在以后的修订中放宽了,C ++ 17弃用了result_of
。