右辺値になる操作の簡単な例を考え出そうとしています。
このテストケースは機能するはずでしたが、驚くべきことに(私にとって)、2つのint
sを追加した結果は右辺値(参照)ではありません。ここで何が欠けていますか?
void test(int i, int j)
{
// this assert should pass, but fails:
static_assert(std::is_same<decltype(i + j), int&&>(), "i + j should be a rvalue");
// this assert passed, but should fail:
static_assert(std::is_same<decltype(i + j), int>(), "this assert should fail...");
}
i + j
は prvalue式 、
Prvalue( "pure rvalue")式は、IDを持たず、から移動できる式です。
a + b、a%b、a&b、a << b、およびその他すべての組み込み算術式。
xvalue ではありません、
Xvalue( "expiring value")式は、アイデンティティを持ち、そこから移動できる式です。
そして decltype specifier は、T&&
ではなくprvalueに対してT
を生成します。
a)式の値カテゴリがxvalueの場合、decltypeはT &&;を生成します。
b)式の値カテゴリが左辺値の場合、decltypeはT&;を生成します。
c)式の値カテゴリがprvalueの場合、decltypeはTを生成します。
std::move
でxvalueにすることができます:
static_assert(std::is_same<decltype(std::move(i + j)), int&&>(), "std::move(i + j) is a xvalue then this static_assert won't fail");
@songyuanyaoの Answer に基づいて、私の間違いが間違ったことをチェックしていることに気づきました。私の意図は、_i+j
_の結果がバインドされるかどうかをチェックすることでした。 右辺値参照ですが、が右辺値参照であるかどうかを確認しました。
decltype値のカテゴリに基づいてタイプを推測します。参照型値はバインド先:
1)式の値カテゴリが
xvalue
の場合、decltypeは_T&&
_を生成します。
2)式の値カテゴリがlvalue
の場合、decltypeは_T&
_を生成します。
3)式の値カテゴリがprvalue
の場合、decltypeはT
を生成します。
リストに示されているように、C++ 11以降、rvalues
は最下位レベルの個別のカテゴリとして存在しません。prvalues
とxvalues
の両方を含む複合カテゴリになりました。書かれた質問は、式が_rvalue reference
_であるかどうかを尋ね、それがxvalue
であるかどうかをチェックします。
上記のリストから、_i+j
_がprvalue
であることが明らかであるため、3番目のケースが適用されます。これは、decltype(i + j)
がint
であり、_int&&
_ではない理由を説明しています。 xvalues
とprvalues
bind to右辺値参照の両方。
したがって、_i+j
_が_lvalue reference
_または_rvalue reference
_にバインドされているかどうかを確認することにより、実際にそれがバインド _rvalue reference
_であることを確認します。
_void foo(const int& f)
{
std::cout << "binds to lvalue reference" << std::endl;
}
void foo(int&& f)
{
std::cout << "binds to rvalue reference" << std::endl;
}
void test(int i, int j)
{
foo(i); // lvalue -> lvalue ref
foo(std::move(i)); // xvalue -> rvalue ref
// (std::move converts the argument to a rvalue reference and returns it as an xvalue)
foo(i + j); // prvalue -> rvalue ref
}
_
結論:_i+j
_はnot右辺値参照、しかし、それは1つにバインドします。