1

R値の出力がL値と異なる理由を誰かに説明してもらえますか?

#include <iostream>
#include <vector>
using namespace std;

template<typename Ct>
struct  ct_wrapper {
    Ct&& ct; // R or L ref
    explicit ct_wrapper(Ct&& ct) 
      : ct(std::forward<Ct>(ct)) { std::cout <<  this->ct[1];};
};

int main() {

    // L-val
    vector<int> v{1,2,3};
    ct_wrapper<vector<int>&> lv(v);
    cout << endl << lv.ct[0] << lv.ct[1] << lv.ct[2] << endl;

    // R-val
    ct_wrapper<vector<int>&&> rv(vector<int>{1,2,3});
    cout << endl << rv.ct[0] << rv.ct[1] << rv.ct[2] << endl;
}

出力 (gcc48 と clang32 で同じ):

2
123
2
003

答え

Johannes Schaub とのチャットで少し埋もれてしまったので、ここに記載します。

一時的なベクトルが r-value-ref member-variable を初期化する場合rv.ct、特別な例外があるため、一時的な有効期間は延長されません: [class.temporary]p5: "コンストラクターの ctor-initializer (12.6.2) で参照メンバーに一時的にバインドされています。コンストラクターが終了するまで持続します。」

4

3 に答える 3

7

あなたのメンバーは単なる参照だからです。rv2 番目のケースでは、ローカル変数の定義が終了した後、それが参照するオブジェクトは既に死んでいます。したがって、後のアクセスcoutは未定義の動作です。

于 2012-09-01T09:35:05.913 に答える
3

ぶら下がっている参照にアクセスしているため、プログラムの動作は未定義です。一時ベクトルは、それが表示される完全な式の最後で破棄されますが、それでも、一時ベクトルへの参照は保持されます。

于 2012-09-01T09:35:53.120 に答える
2

r値の場合、一時を参照にバインドします。最後の出力ステートメントに到達すると、すでに消えています。

于 2012-09-01T09:36:00.433 に答える