2
class Myclass
{    
public:
    Myclass() = default;
    ~Myclass() = default;
    Myclass(Myclass&&) = default;
    Myclass& operator=(Myclass&&) = default;

    Myclass(const Myclass&) = delete;

    Myclass& operator=(const Myclass&) = delete;
    int i = 0;
};

Myclass GetObj()
{
    Myclass obj;    
    return obj;
}

Myclass WrapperOfGetObj()
{
    Myclass&& Wrapobj = GetObj();
    Wrapobj.i = 1; // Will it work?

    return std::move(Wrapobj);
}

int main()
{
    return 0;
}

いくつか質問があります: 1)WrapperOfGetObj関数でWrapobjxvalue なので、そのメンバーに値を割り当てることができます (xvalue - 期限切れになります!!)
2) のストレージはxvalue何ですか? これは自動保存ではありませんか?
3)いつにxvalueなるglvalueか、いつになるrvalueか(上記のコンテキストの例は、これを明確にします)。

4

2 に答える 2

3

Wrapobjは左辺値です。名前付き変数はすべて左辺値です。

宣言された変数の型と、変数の名前で構成される式の型と値のカテゴリが混同されていると思います。

decltype(Wrapobj)を与え MyClass&&ます。誰かが「Wrapobj右辺値参照です」と言うとき、彼らは宣言された型について話している。しかし、Wrapobjが式で使用される場合、 typeMyClassと value カテゴリがありますlvalue

参照型の式などありません。また、式の型と値のカテゴリは、式が一時オブジェクトを表すかどうかには直接関係しません。

質問 2 の場合:「xvalue」は式の値カテゴリです。式にはストレージがありません。オブジェクトにはストレージがあります。参照はストレージを使用する場合と使用しない場合があります (指定されていません)。参照の保存と、それが参照するオブジェクトの保存を区別してください。

の戻り値GetObj()一時オブジェクトです。一般的な実装では (自動オブジェクトと同様に) スタックが使用されますが、標準では実際には一時オブジェクトの保存期間が指定されていません。C++17 は、この分野で標準の文言を改善している可能性があると思います。

于 2016-11-07T06:11:03.130 に答える
-1

これらの回答は役に立ちます...

右辺値参照はダングリング参照を許可しますか?

rvalue、lvalue、xvalue、glvalue、および prvalue とは何ですか?

xvalues、glvalues、および prvalues の実際の例は?

Myclass WrapperOfGetObj()
{
    Myclass&& Wrapobj = GetObj();
    Wrapobj.i = 1; // Will it work?

    return std::move(Wrapobj);
}

1)WrapperOfGetObj関数では、Wrapobjはxalueであるため、そのメンバーに値を割り当てることができます(xvalue-期限切れになります!!)

WrapobjGetObj() によって返される prvalue への右辺値参照です。その prvalue の有効期間は右辺値参照の有効期間まで延長されているWrapobjため、アクセス.i = 1は問題ありません。

2) xvalue のストレージは何ですか? これは自動保存ではありませんか?

Wrapobjの参照されたオブジェクトには自動ストレージがあり、WrapperOfGetObj が終了すると破棄されます。

3) xvalue が glvalue になるとき、および rvalue になるとき (上記のコンテキストの例は、これを明確にします)。

xvalue は常に glvalue です。glvalues は、すべての「xvalues」とすべての「lvalues」の和集合であり、「同一性を持つ」ことを意味します。xvalue は常に右辺値でもあります。これは、すべての "xvalues" とすべての "prvalues" の和集合であり、"移動できる" ことを意味します。

したがって、上記の例でWrapobjは、glvalue (ID があるため)、rvalue (移動できるため)、および xvalue (移動可能で ID があるため) です。

WrapperOfGetObj() から戻るstd::move(Wrapobj)と、 によって返された xvalue から新しい prvalue を構築していstd::moveます。

于 2016-11-06T16:26:51.547 に答える