C++11標準ライブラリおよびBoost.Utilityライブラリで提供されるdeclval<T>ンプレートの戻り値型についてメモ。
template<class T> typename add_rvalue_reference<T>::type declval() noexcept;
戻り値型が単純なT&&となっていない理由は、テンプレートパラメータT=void型を与えたとき、ill-formedなvoid&&ではなくvoidに推論させるため。*1
template<class T> T&& declval() noexcept; // NG: declval<void>()がvoid&&になってしまう
C++11(N3337) 20.9.7.2 Table 53よりadd_rvalue_referenceメタ関数の定義を引用。
If
Tnames an object or function type then the member typedeftypeshall nameT&&; otherwise,typeshall nameT. [Note: This rule reflects the semantics of reference collapsing (8.3.2). For example, when a typeTnames a typeT1&, the typeadd_rvalue_reference<T>::typeis not an rvalue reference. -- end note]
関連URL
- c++ - Why is 'declval' specified in terms of 'add_rvalue_reference<T>::type' and not 'T&&'? - Stack Overflow
- cppreference declval, cpprefjp declval
*1:N3338 8.3.2/p1: "A declarator that specifies the type "reference to cv void" is ill-formed."