2015-02-05 8 views
6

Nie rozumiem, dlaczego nie można użyć std::reference_wrapper takiego:Dlaczego std :: reference_wrapper niejawnie rzutuje na odwołanie podczas wywoływania funkcji składowej?

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

Dlaczego musimy użyć funkcji get() członkiem? Wygląda na to, że std::reference_wrapper ma niejawną konwersję na T& poprzez operator T&() const noexcept, zobacz http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper , więc dlaczego nie jest v[0] niejawnie przekonwertowane na odniesienie?

W innych sytuacjach, takich jak

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

ta konwersja odbywa (zakładam tu, że Foo przeciążenia operator<<)

+2

Jest to dostęp dla członków klasy. Funkcja elementu zawsze jest sprawdzana w typie LHS i nie są stosowane żadne niejawne konwersje. Alternatywa (przeciążenie 'operatora') jest trudna do określenia poprawnie; od lat pojawiały się liczne propozycje dotyczące tej kwestii. Najnowszym jest http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4173.pdf –

Odpowiedz

14

Ponieważ . jest zawsze używany do członków dostępu obiektu to zaaplikowana. Konwersje typu nie są uwzględniane.

Istnieje proposal, aby umożliwić przeciążenie operator., aby włączyć dokładnie to, co chcesz, ale to nie będzie standardem, dopóki przynajmniej C++ 17, jeśli w ogóle.

-1

Jest to ograniczenie językowe wskazane przez @MikeSeymour.

I to jest powód, dlaczego myślę std::reference_wrapper powinien mieć przeciążony operator& która zwraca adres zawiniętego obiektu:

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

tak aby później można wykorzystać &Foo->f() lub (*&Foo).f() zamiast Foo.get().f() lub static_cast<T&>(Foo).f().

Powiązane problemy