2015-02-05 14 views
6
biri böyle bir std::reference_wrapper kullanamazsınız neden tam olarak anlamıyorum

:Neden üye işlevini çağırırken std :: reference_wrapper örtük olarak bir referansa yayınlanmadı?

#include <vector> 
#include <functional> 

struct Foo 
{ 
    void f() {}; 
}; 

int main() 
{ 
    std::vector<std::reference_wrapper<Foo>> vrFoo; 
    Foo foo; 
    vrFoo.push_back(foo); 
    // vrFoo[0].f(); // error 
    vrFoo[0].get().f(); // or static_cast<Foo&>(v[0]).f(); 
} 

Neden get() üye işlevi kullanmak gerekiyor? std::reference_wrapper'un operator T&() const noexcept aracılığıyla T&'a dolaylı bir dönüşümü olduğu anlaşılıyor, bu nedenle http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper 'a bakın, bu nedenle neden v[0] bir referansa dönüştürülmez? Diğer durumlarda

gibi

std::cout << v[0] << std::endl 

bu dönüşüm . Çünkü

+2

Bu bir sınıf üyesi erişim. Üye işlevi her zaman LHS'nin türüne bakılır ve örtülü dönüşümler geçerli değildir. Alternatif (aşırı yükleme 'operatörü.) Doğru şekilde belirtilmesi zordur; Bu konuda yıllar boyunca çok sayıda teklif var. En yenisi http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4173.pdf –

cevap

14

hep uygulanacağına nesnenin erişim üyelerine kullanılır (I Foo aşırı yükler operator<< olduğu varsayılır) gerçekleşir. Tür dönüşümleri dikkate alınmaz.

operator.'un aşırı yüklenmesine izin vermek için bir proposal var, tam olarak ne istediğinizi etkinleştirmek için, ancak en azından C++ 17'e kadar standart olmayacak.

-1

Bu, @MikeSeymour'un işaret ettiği gibi bir dil sınırlamasıdır.

template<class T> 
struct reference wrapper{ 
    ... 
    T* operator &(){return ptr;} 
} 

Böylece sonradan birini kullanabilirsiniz &Foo->f() veya (*&Foo).f() yerine Foo.get().f() veya static_cast<T&>(Foo).f():

Ve bu std::reference_wrapper sarılı nesnenin adresini döndüren bir aşırı operator& olması gerektiğini düşünüyorum nedeni budur.

İlgili konular