请考虑以下代码:
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
?
你可以只使用C ++ 11而不使用std::result_of
的decltype来实现这个目的:
using type2 = typename std::result_of<F&&(Args&&...)>::type;
一旦你开始使用C ++ 17,你应该用std::result_of
替换std::invoke_result
,如documentation中所述。
也许您想要使用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>())...));
}
希望这可以帮助
从这开始:
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,不允许返回某些类型等)。