2016-01-16 8 views
11

んがトン(* this)を使用すると、例外RuntimeErrorを結果:トン(STD :: refを(*これは)私は、次の例ではありませ

#include <iostream> 
#include <functional> 

struct Tmr { 
    typedef std::function<void(void)> Callback; 
    Callback cb; 

    Tmr(Callback cb_) : 
     cb(cb_) 
    { 
    } 

    void timeout() 
    { 
     cb(); 
    } 
}; 

struct Obj { 
    struct Tmr t; 

    Obj() : 
     t(std::ref(*this)) 
    { 
    } 

    void operator()() 
    { 
     std::cout << __func__ << '\n'; 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    Obj o; 

    o.t.timeout(); 

    return 0; 
} 

をこれは細かい動作しますが、最初に私はObjのコンストラクタを持っていました。私は、メンバ関数への参照のみが上のメンバーを呼び出すためのオブジェクト私のコールバックに保存されている、とされていないため、

何これは推測

ランタイムエラーになり
Obj() : 
    t(*this) 

:として。しない私がObj() : t(std::ref(*this))を実行したときにstd::refが何をするのか理解しており、なぜこれがプログラムを動作させるのでしょうか。誰が何が起こっているのか、それがどのように機能するかについて、何か光を当てることができますか?

+0

いいえObj():t(* this) 'はうまくいきます。あなたの 'Callback'は関数型で、' Obj'もそうです。 –

+0

@ Jean-BaptisteYunèsObj():t(* this)が実行時にクラッシュするので、コンパイラが無効なコードを生成していると言っていますか? – binary01

+2

これは私のg ++​​ std C++ 11コンパイラで動作し、なぜあなたのためにうまくいかないのか分かりません。 –

答えて

5

あなたがt前に*thisをコピーしている参照渡していない初期化されています - 彼らは未定義の動作である、初期化してきた前にあなたがtとそのコールバックメンバーをコピーしていることを意味しています。理由は初期化されていないコールバックオブジェクトのコピーの

(そしてstd::functionのコピーコンストラクタは、実際のクラッシュを引き起こすもので初期化されていないポインタで指さ何コピーしようとする可能性がある。)

1

あなたのコードがクラッシュします。以下のイベントのシーケンスを見ることができます:

1. Copy constructor of Obj is called in t(*this) 
2. Copy constructor of Tmr is called as t is a member of Obj 
3. Copy constructor of Callback is called as cb is a member of Tmr 
4. Execution fails while trying to copy from uninitialized Callback object. 

を使用すると、Objのコピー作成をバイパスします。それがクラッシュしない理由です。

関連する問題