std::result_of<T>
要求T
是一種類型 - 但不只是任何類型。 T
必須是一個函數式所以result_of
這部分特將被使用:
template <class Fn, class... ArgTypes> struct result_of<Fn(ArgTypes...)>;
使得:
decltype(INVOKE(declval<Fn>(), declval<ArgTypes>()...))
是公形成(C++ 11 20.9.7.6) 。 (INVOKE在20.8.2中定義)
原因std::result_of<f(int)>
不起作用是因爲f
不是類型 - 它是函數類型的一個實例。要聲明x
是應用於int
的f
返回類型,簡單地寫:
decltype(f(int{})) x;
或者如果你喜歡硬編碼的int
:
decltype(f(32)) x;
如果類型f
然後用:
using FuncPtr = decltype(f);
在所提供的代碼F
(即,不小寫f
)然而是一種類型的,因此F(int)
限定了代表返回F
受理int
爲參數的函數的類型。顯然這不是F的意思! F
的類型是一個結構,它的實例可以使用函數調用操作符。 F
也沒有明確或隱含的構造函數,也可以使用int
等。這如何工作?簡短的回答:模板「魔術」。
本質上,std::result_of
的定義採用類型F(int)
並將返回類型與參數類型分開,以便確定哪種情況的INVOKE()可以使其工作。 INVOKE的情況是:
- F是一個指針,指向用於一些T級
- 一個成員函數如果只有一個參數,F是一個指針,指向類T的數據成員,或者,
- 一架F的實例可以作爲一個功能,即,
declval<F>()(declval<int>())
它可以是一個普通的函數調用或某些類型的函子(例如,像您的例子)。
一旦確定result_of
可以確定有效表達式的返回類型。這是通過result_of
的type
成員返回的內容。
關於這件事的美妙之處在於,result_of
的用戶不需要知道任何有關這個實際工作方式的信息。唯一需要了解的是result_of
需要一個函數TYPE。如果使用的是代碼中不是類型的名稱(例如,f
),則需要使用decltype
來獲取具有這種類型的表達式的類型。
最後,爲什麼f
不能被視爲一個類型的部分原因是模板參數也允許常量值,而f
是一個常量函數指針值。這是很容易證明(使用f
問題的定義):
template <double Op(int)>
double invoke_op(int i)
{
return Op(i);
}
及更高版本:
std::cout << invoke_op<f>(10) << std::endl;
因此,要獲得正確調用f
一些int
表達式的返回值的類型一會寫:
decltype(f(int{}))
(注:f
不會被調用:編譯器簡單地使用內decltype
表達以確定其結果即在這種情況下它的返回值。)
的解決方案是使用本'的std ::的result_of :: type x;'。如果您想深入瞭解,請查看http://stackoverflow.com/q/2763824/893693 –
inf
2012-07-13 13:22:51