请考虑以下代码:
template <class F, class... Args>
void function(F&& f, Args&&... args)
{
using type1 = decltype(std::forward<F>(f)(std::forwards<Args>(args)...));
using type2 = decltype(/*equivalent expression but only using types */);
}
是否可以在所有情况下使type2
与type1
相同,但仅使用decltype
表达式中的类型,或者仅使用F
和Args
而非f
和args
?
答案 0 :(得分:6)
您可以仅使用C ++ 11而不使用std::result_of
的
using type2 = typename std::result_of<F&&(Args&&...)>::type;
一旦开始使用C ++ 17,您应该按documentation中的说明将std::result_of
替换为std::invoke_result
。
答案 1 :(得分:3)
使用declval
所需的解决方案可能就是:
template <class F, class... Args>
void function(F&& f, Args&&... args)
{
using type1 = decltype(std::forward<F>(f)(std::forward<Args>(args)...));
using type2 = decltype(std::forward<F>(declval<F>())(std::forward<Args>(declval<Args>())...));
}
希望这有帮助
答案 2 :(得分:1)
从这开始:
decltype(std::forward<F>(f)(std::forwards<Args>(args)...));
改为:
decltype(std::declval<F>()(std::declval<Args>()...));
并完成了。 std::declval<T>()
是一个没有实现的函数,其返回类型与std::forward
相同。
c++11有std::result_of
(而c++14有std::result_of_t
),但这有一些小问题使其不完美。您可以使用&&
:
std::result_of_t< F&&( Args&&... ) >
在c++17中,他们添加invoke_result
来修复这些怪癖:
std::invoke_result_t< F, Args... >
怪癖是因为函数调用签名中允许的类型不是所有类型,并且语言以某种方式静默调整它们(删除顶级const,不允许返回某些类型等)。 / p>