簡短的回答是:
template<class Sig>
using Result_of = typename std::result_of<Sig>::type;
會讓你的用例的 「工作」。有些會因編碼錯誤或類型不匹配而無法編譯。
但是,這不是最好的方法。
C++ 11編譯器並不都實現最佳實踐版本result_of
:即SFINAE友好版本。如果您正在撰寫幫手,我會以最佳做法風格進行操作。
首先,別名做decltype
評價:
template<class F, class...Args>
using invoke_result = decltype(std::declval<F>()(std::declval<Args>()...));
下,一些元編程樣板我覺得有用:
namespace details {
template<class...>struct voider{using type=void;};
template<class...Ts>using void_t=typename voider<Ts...>::type;
template<template<class...>class Z, class, class...Ts>
struct can_apply:std::false_type{};
template<template<class...>class Z, class...Ts>
struct can_apply<Z, void_t<Z<Ts...>>, Ts...>:std::true_type{};
}
template<template<class...>class Z, class...Ts>
using can_apply=details::can_apply<Z,void,Ts...>;
can_apply< template, args... >
回答這個問題:「正在申請的ARGS ...到模板有效?「。這非常有用。
正如我們在C++ 11的土地,一個enable_if_t
別名使得代碼看起來更漂亮:
template<bool b, class T=void>
using enable_if_t=typename std::enable_if<b,T>::type;
我們現在可以開始在result_of_t
別名工作:
namespace details {
template<class Sig,class=void>
struct result_of {};
template<class F, class...Args>
struct result_of<
F(Args...),
enable_if_t<can_apply<invoke_result, F, Args...>>
> {
using type=invoke_result<F,Args...>;
};
}
template<class Sig>
using result_of_t = typename details::result_of<Sig>::type;
,我們做。
這會生成一個名爲result_of_t
的SFINAE友好型別名,它在任何兼容的C++ 11編譯器中都可以像高質量的C++ 14 std::result_of_t
一樣工作。它在MSVC上不能很好地工作,但那是因爲MSVC2015仍然沒有充分實現C++ 11。
所有的例子都應該使用result_of_t
代替Result_of
,或者因爲它們無效而失敗。
int ff(int){return 2;}
typedef bool(*PF)(int);
auto fx = [](char ch){return tolower(ch);};
result_of_t<decltype(&ff)()> r1 = 7;
失敗,因爲你必須通過一個int
到ff
。這會工作:
result_of_t<decltype(&ff)(int)> r1 = 7;
result_of_t<PF(int)> r2 = 2;
這個分配2
到bool
。所以它...的作品。
result_of_t<decltype(fx)(char)> r5 = "a";
這個分配"a"
到int
,這可能不是你想要的。 (tolower
在C/C++中返回int
)。
我們可以通過解決這個問題:
auto fx = [](char ch)->char{return tolower(ch);};
result_of_t<decltype(fx)(char)> r5 = 'a';
你絕對確保OP想要使用逗號分隔的版本? – Yakk
@Yakk我不知道OP還可以想要什麼? – Barry
'模板使用Result_of = typename std :: result_of :: type;'是我的猜測,因爲這使得他的用例按原樣編譯。 –
Yakk