yohhoyの日記

技術的メモをしていきたい日記

declvalの戻り値型とvoid

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 T names an object or function type then the member typedef type shall name T&&; otherwise, type shall name T. [Note: This rule reflects the semantics of reference collapsing (8.3.2). For example, when a type T names a type T1&, the type add_rvalue_reference<T>::type is not an rvalue reference. -- end note]

関連URL

*1:N3338 8.3.2/p1: "A declarator that specifies the type "reference to cv void" is ill-formed."