您的版本不適用於例如指向成員。再仔細,但仍然沒有確切的版本是:
template <class F, class... Args>
auto async(F&& f, Args&&... args)
-> future<decltype(ref(f)(forward<Args>(args)...))>;
與std::result_of
剩下的唯一的區別是,這個轉發仿函數作爲一個左值(一個問題,你的版本也萬股)。換句話說,這種呼叫的結果(通過std::reference_wrapper<F>
)是typename std::result_of<F&(Args...)>::type
。
這是一個尷尬的局面,其中標準庫的幾個組成部分(僅舉幾例,除了那些我們剛剛見證:std::thread
,std::bind
,std::function
)在一個難以捉摸的援引術語規定(F, a0,a1,...,aN)僞表達式,它不完全等同於f(a0, a1, ... aN)
。由於std::result_of
是其中一個組件,並且實際上用於計算結果類型INVOKE,這就是您注意到的差異。
因爲沒有std::invoke
與std::result_of
類型特徵串聯,我認爲後者僅用於描述例如當您的代碼調用它們時,相關標準庫組件的返回類型。如果你想要一個簡潔而自我記錄的寫作方式,例如返回類型(一個非常有價值的目標是爲了便於閱讀,比噴灌decltype
無處不在),那麼我建議你寫你自己的別名:
template<typename F, typename... A>
using ResultOf = decltype(std::declval<F>()(std::declval<A>()...));
(如果你想別名被用作ResultOf<F(A...)>
代替ResultOf<F, A...>
那麼你需要一些機器來模式匹配功能簽名。)
這個別名的一個額外的好處是它是SFINAE友好的,不像std::result_of
。是的,這是它的另一個缺陷。 (公平地說,雖然已經對即將推出的標準進行了修改,但實施已經進行了相應的修改。)
如果您使用這樣的特性,您可以使用指針,因爲您可以修改指向成員的指針std::mem_fn
。
是否用'result_of'指定_或_implemented_?因爲這可能只是實現它的傢伙的心血來潮,或者它可能已經在'decltype'之前實現到目標編譯器。在Apple的libC++中,它既不使用。 – zneak 2013-03-28 04:03:48
@zneak:我展示的聲明被複製出標準,所以'std :: async'是通過'result_of'指定的。實現可以做任何他們喜歡的事情,只要它們提供的行爲與指定的行爲相同即可。 – KnowItAllWannabe 2013-03-28 06:03:03
只要知道'std :: result_of'語法有一些[不幸的含義](http://stackoverflow.com/a/15489789/500104)。 – Xeo 2013-03-28 07:44:15