2017-11-13 13 views
3

レンジ・アクセス機能std::beginが(コンテナのために)宣言されています。それは単にstd :: beginが末尾の戻り値の型構文を使用する理由次のように

template< class C > 
decltype(C::begin) begin(C& c); 

ない理由

template< class C > 
auto begin(C& c) -> decltype(c.begin()); 

私だけだろうこれら二つの間に違いはありますか?

+2

あなたはそれを試しましたか?もしそうなら、何が起こったのですか?そうでない場合は、どうしてですか? – Useless

+0

最初のバージョンは、 'begin'が呼び出されるときに型を取得します。 2番目のバージョンは 'begin'の型を取得します。 – nwp

+0

'C :: begin'は(おそらく)メンバ関数であり、' decltype(C :: begin) 'は' Iterator(C :: *)() '(メンバ関数へのポインタ)のようなものです。 'イテレータ '。 – lisyarus

答えて

8

同等のコードは、潜在的に複数のエラーが発生しやすい長く、

template< class C > 
decltype(::std::declval<C &>().begin()) begin(C& c); 

あろう。

3

このバージョン

template< class C > 
decltype(C::begin) begin(C& c) 

が動作しません、

  1. decltype(C::begin)は方法の種類ではなく、メソッド呼び出しの結果の型を意味し、とにかく
  2. ので、 beginメソッドが標準コンテナのためにオーバーロードされており、評価されていなくても関数呼び出しのコンテキストがなくても、コンパイラはどのオーバーロードを含めるべきかを決定できません。

VTTで表示されるバージョンは、オーバーロードを解決できる未評価の関数呼び出しコンテキストを作成することで修正されています。末尾のdecltypeを使用する代わりに、引数タイプの繰り返しが保存されます。

関連する問題