2017-01-04 12 views
1

はVS2015でいくつかのコードである:ケース3内rvalue参照引数は、rvalue参照パラメータのconst lvalue参照よりも好きなのはなぜですか?ここ

class Elem 
{ 
public: 
    Elem(int i) : a(i) {} 
    Elem(Elem && other) = default; 
    Elem(const Elem & other) = default; 
private: 
    int a; 
}; 

int main() 
{ 
    std::vector<Elem> vv; 

    // case 0 
    vv.push_back(Elem{ 0 }); // call push_back(Elem &&); 

    // case 1 
    Elem e1{ 1 }; 
    vv.push_back(e1); // call push_back(const Elem &); 

    // case 2 
    Elem e2{ 2 }; 
    auto & lref = e2; 
    vv.push_back(lref); // call push_back(const Elem &); 

    // case 3 
    Elem e3{ 3 }; 
    auto && rref = std::move(e3); 
    vv.push_back(rref); // call push_back(const Elem &); 

    // case 4 
    Elem e4{ 4 }; 
    vv.push_back(std::move(e4)); // call push_back(Elem &&); 

    return 0; 
} 

rrefのタイプは、右辺値リファレンスであり、その値カテゴリはlvalueあり、push_back(const Elem &)を呼び出します。ケース4では

は、効果的な現代のC++項目23によれば、std::moveの実装はstd::move(e4)のタイプElem &&であり、その値カテゴリはprvalueで、push_back(Elem &&)を呼び出し

// C++ 14  
template<typename T> 
decltype(auto) move(T&& param) 
{ 
    using ReturnType = remove_reference_t<T>&&; 
    return static_cast<ReturnType>(param); 
} 

ようなものです。式の型と​​値カテゴリを行い、実際にTconst T &T &&間のオーバーロードの解決時に何をすべきか

のでlvalueT&&の試合const T &、およびprvalueT&&の試合T&&、?


申し訳ありませんが、私の問題を明確に記述していません。非常に多くのリンクによると、引数の値カテゴリがprvalueであれば、T&&の関数が呼び出されます。値カテゴリがlvalueの場合は、const T &の関数が呼び出されます。

パラメータの型が参照のときに、値のカテゴリが参照結合についてチェックされている間に、引数の型がオーバーロード解決に使用されていると言うことはできますか?

+5

変数に名前が付いたらすぐに左辺値 –

+0

http://stackoverflow.com/a/18766736/390913 – perreal

答えて

0

変数名(この場合は "e3")を割り当て、この変数を使用して関数を渡すとき、それは左辺値になります。そのため、関数の "lunue"バージョンを呼び出すのが "push_back"です。しかし、ケース4で "std :: move(e4)"として渡しているときは、それは右辺値として渡され、右辺値の "push_back"関数を呼び出す理由です。

ちょうどウェブを経由して私はほとんど同じような言葉でrvalueの参照を説明するこのリンクを見つけました。あなたはこのリンクをチェックすることができます。

http://simpletechtalks.com/rvalue-references/

1

rrefそれは名前を持っているので、左辺値であるので、push_back(const Elem &)が呼び出されます。名前の変数にmoveは無用ですが、あなたがそれを主張する場合は、あなたにコードを変更することができます

// case 3 
Elem e3{ 3 }; 
auto && rref = std::move(e3); 
vv.push_back(std::forward<decltype(e3)>(rref)); 

そしてpush_back(Elem &&)と呼ばれています。または、ケース4で行ったことをやり直してください。

関連する問題