2016-03-30 4 views
11

を転送するために、私は疑問を持っている:なぜ私は 右辺値は、私が読んでいる<a href="http://thbecker.net/articles/rvalue_references/section_08.html" rel="noreferrer">reference collapsing rules</a>参照

template<typename T> 
void foo(T&&); 

T

によるものと推定される 右辺値を渡す場合はどうなりますか?

を関数Tに渡すと、std::stringと推測されますが、なぜstd::string&&になりませんか?私にはもっと意味がありましたが、タイプ自体にTを推論する根本的な理由は何ですか?

答えて

11

これだけで私たちは、テンプレート型推論から、一般的に期待するものとラインアップ:

template <class T> void vfoo(T); 
template <class T> void lfoo(T&); 
template <class T> void cfoo(T const&); 
template <class T> void ffoo(T&&); 

std::string x; 
vfoo(x);   // deduce T = std::string 
lfoo(x);   // deduce T = std::string 
cfoo(x);   // deduce T = std::string 
ffoo(x);   // deduce T = std::string& ! 
ffoo(std::move(x)); // deduce T = std::string 

the original paperから、重点鉱山:

に一致する左辺値引数を使用して、関数テンプレートの種類を推定rvalue参照である場合、その型はlvalue参照型として推定されます。控除に右辺の引数が与えられると、型減算が他の型と同様に進められます。

これは、左辺の控除のケースです。これは例外的なケースです。これは、タイプ控除ルールで余分な文章が得られる理由です。右辺のケースは典型的なもので、演繹された型に貼り付ける単純な精神モデルと整列して、どのような関数が最終的に終わるかを調べます。 T&&といい、std::stringと表示されていますか? T = std::stringを取得し、引数がstd::string&&となるようにします。チェック。

3

ファンクションパラメータタイプが& &であるため、式の 'T'部分を推測しています。

したがって、 'passing' std::string&&T&&に設定すると、Tstd::stringと推定されます。

std::stringをのTに代入すると、std::string&&が得られます。

これは、式T const&Tを推測するのと同じ種類です。 const参照によってstd::stringが「渡された」とき、T部分はstd::stringと推定されます。

+2

最後の文章が間違っています。 'template void foo(T)'は参照型を推論しません。 – Oktalist

+0

@Oktalistあなたが正しいです - 私はそれを削除しました。 – Pete

関連する問題