2016-01-16 18 views
11

yapar ederken şu örneği vardır:kullanma t (* this) sonuçları RuntimeError, t (std :: ref (* this) değil

#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; 
} 

Bu iyi çalışır, ancak başlangıçta ben Obj yapıcısı vardı olarak:.

bir çalışma zamanı hatası ile sonuçlanır
Obj() : 
    t(*this) 

Ben üye işlevine yalnızca bir referans benim geri arama saklanır değil, nesne üzerinde üyesi çağırmak çünkü bu sanırım

ne. yapamaz std::ref'un Obj() : t(std::ref(*this)) yapmamı ne anlama geldiğini ve bunun programın çalışmasını neden yaptığını anlaması. Birileri neler olup bittiğine biraz ışık tutabilir mi ve nasıl çalışır?

+0

Hayır 'Obj(): t (* this)' iyi çalışıyor. 'Geriçağırım'' Obj’inizin de bulunduğu bir functor türüdür. –

+0

@ Jean-BaptisteYunès Derleyicinin geçersiz kod oluşturduğunu mu söylüyorsunuz, çünkü Obj(): t (* this) 'çalışma zamanında çöküyor, ancak iyi çalışıyor mu? – binary01

+2

G ++ std C++ 11 derleyicimde çalışıyor ve neden sizin için çalışmadığını göremiyorum. –

cevap

5

sen başlatıldı edilmiştir t önce *this kopyaladığınız referans olarak geçemiyor zaman - sen t ve tanımsız davranıştır onlar başlatıldı oldum önce onun geri arama üyesini, kopyalıyorsun anlamına geliyor.

(Ve std::function kopyası yapıcısı gerçek kazasında neyin sebep olan bir başlatılmamış pointer tarafından işaret ne kopyalamayı deneyin muhtemeldir.)

1

Kodun çünkü başlatılmamış geri arama nesnesinin kopyalama çöker. Aşağıdaki olay dizisi görebilirsiniz: std kullanarak

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. 

:: Eğer Obj bir kopyası oluşturma atlamak ref; Bu yüzden çökmez.