2017-02-19 13 views
0

次のコンパイル:何かへのconst参照を返す、警告:ローカルの一時的なオブジェクトへの参照を返す

namespace platform { 
    struct event {}; 
    struct keyboard_event : public event {}; 

    const platform::event& wait_event() 
    { 
    return platform::keyboard_event(); 
    } 
} 

int main(int argc, const char* argv[]) 
{ 
    const platform::event& event = platform::wait_event(); 
    return 0; 
} 

が打ち鳴らすと、次の警告を生成する

main.cc:7:12: warning: returning reference to local temporary object [-Wreturn-stack-address] 
    return platform::keyboard_event(); 
      ^~~~~~~~~~~~~~~~~~~~~~~~~~ 

しかし、それはその寿命をしない拡張します?現在のドラフトは私のためにロードされていない

ので、私が代わりにcppreference.comを引用します:constの左辺値参照または右辺値参照に結合することによって延長することができる

一時オブジェクトの寿命を(C++ 11以降)、詳細はリファレンスの初期化を参照してください。

どのように私はこれを書き直しても同じ効果を得ることができますが、警告は避けてください。

+0

'platform :: keyboard_event()'はr値です。 'const&'でバインドして返します。しかし、temp、const、またはnotへの参照を返すことはできません。これは古典的な "一時的な参照を返す"警告です。 – xinaiz

+0

"参照の初期化を参照してください"のリンクをたどった場合、cppreferenceは "return文の関数の戻り値に一時的にバインドされていません" – Cubbi

答えて

2

いいえ、「参照を返す」は魔法のように生涯を延長しません。

struct Foo{}; 

{ 
    const auto & r = Foo{}; // Foo object not destroyed at semicolon... 
    // ... 
} 
// ... but is destroyed only here. 

あなたprvalueがバインドされていない:prvalueを参照変数にバインドされている、とprvalueの寿命は、変数のように拡張されたときに寿命が延長され

だけですいかなる変数にも適用されず、従って寿命は延長されない。

(静的でないクラスのデータメンバーは、この考慮事項では「変数」としてカウントされないため、クラスにリファレンスメンバーがある場合は、コンストラクタのイニシャライザリストでライフタイムを延長することもできません)。

+0

これは未定義の動作スタックは変更されませんでした。したがって、定数値またはr値参照によって生存期間を延ばすことは、どのようなシナリオでも参照渡しに使用できません。 –

+0

@CasperBeyerいいえ、値で戻ってきます - この場合は、 –

+0

の値で戻り値が返されます。 (構造体ごとに異なるデータセットがあると仮定して) –

関連する問題