2012-01-21 9 views
17

§20.2.4 [declval]なぜ '宣言'は 'T &&'ではなく、 'add_rvalue_reference <T> :: type'で指定されていますか?

template <class T> 
typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated operand 

なぜここadd_rvalue_referenceを使うのか? add_rvalue_reference§20.9.7.2 [meta.trans.ref]から

Tもし名前オブジェクトまたは関数型のその後type typedefのメンバーがT&&に名前を付けるものとします。それ以外の場合は、typeの名前はTとなります。 [注:このルールは、参照縮退(8.3.2)のセマンティクスを反映しています。たとえば、タイプTのタイプがT1&の場合、タイプadd_rvalue_reference<T>::typeは正の値ではありません。 末端ノートは] add_rvalue_reference以来

は、なぜだけではなく、次のようなT&&を使用とにかく崩壊の参照を反映することを意図していますか?

template<class T> 
T&& declval(); 

何が問題になる可能性がありますか? 2つのバージョンの違いは何ですか?

+1

「どうして間違っていますか?」アヒル! –

+3

@ LightnessRacesinOrbit:Err ..何?ちょうど私が何かを見落としたから-1を得ていますか?面白いもの... – Xeo

+1

@ライトネス今_that_は無意味です。 –

答えて

14

これが実際の理由であるかどうかわかりませんが、add_rvalue_referencevoidの動作が異なります。

add_rvalue_reference<void>::typeは、単にvoidです。

void&&はエラーです。

+0

良い点。しかし、実際に 'std :: declval ()'が必要なのはいつですか?私は式SFINAE 'decltype(t.size()、std :: declval ()、std :: true_type)'などでしか想像できませんが、 'void()'ははるかに便利で、全く同じです。 – Xeo

+1

@Xeoおそらく、テンプレートのクラスとして 'void 'を許可するテンプレートクラスですか? 'テンプレートクラスfoo {... declval ...}; foo バー; '。これはまれであるかもしれませんが、必要がなくなったときに機能する方が、必要なときに機能しない場合よりも優れています。 –

+0

私はこれを受け入れるでしょう。なぜなら、私が見落としていたもの/間違っているものを明示しているからです。 "void &&'はエラーです "。 – Xeo

10

いくつかの定義がCV-資格voidのための合理的な結果を与えるdeclval依存します。例はis_assignableある:

template <class T, class U> 
struct is_assignable; 

意図は「整形式」はウェルを参照することです...未評価のオペランドとして

を処理したときに発現declval<T>() = declval<U>()がよく形成されています形式の形になっており、declval<T>自体が整形式であるかどうかは関係ありません。私。我々は一度に一つの事について心配したい。

10

違いは、add_rvalue_reference<>は、Tがオブジェクトまたは関数型の場合、実際には&&部分を追加するだけです。 Tがオブジェクトまたは関数タイプ(たとえばvoid)でない場合は、&&を追加しないでください。

this example on Ideoneを参照してください。
This webpage of Boost's implementation説明:

を機能テンプレートdeclval()の役割は、この機能を使用するか、評価することなく値にタイプTの変換です。この名前は、読者の注意を、が左辺値参照である場合にのみ式declval<T>()が左辺値であるという事実に導くことになっています。そうでない場合は右辺値です。この関数の定義域を拡張するために、我々はまた、テンプレートパラメータとしてCV voidを使用できることを保証し

template<class T> 
typename std::add_rvalue_reference<T>::type declval(); // not used 

にその宣言を変更することで少し良く行うことができます。

関連する問題