2015-02-05 5 views
6

ich genau verstehe nicht, warum man nicht ein std::reference_wrapper wie diese verwenden:Warum wird std :: reference_wrapper nicht implizit auf eine Referenz umgewandelt, wenn die Mitgliedsfunktion aufgerufen wird?

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

Warum müssen wir die get() Member-Funktion nutzen? Es sieht aus wie std::reference_wrapper hat eine implizite Umwandlung zu T& über operator T&() const noexcept, siehe http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper also warum nicht v[0] implizit in eine Referenz umgewandelt?

In anderen Situationen, wie

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

diese Umwandlung stattfindet (Ich gehe davon aus hier, dass Foo Überlastungen operator<<)

+2

Es ist ein Klassenmitglied Zugriff. Die Elementfunktion wird immer in der Art der LHS nachgeschlagen, und es gelten keine impliziten Konvertierungen. Die Alternative (Überladen des Operators) ist schwierig korrekt zu spezifizieren; Im Laufe der Jahre gab es zahlreiche Vorschläge dazu. Die neueste Version ist http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4173.pdf –

Antwort

14

Da . immer den Zugriff auf Mitglieder des Objekts verwendet wird es angewendet wird. Typkonvertierungen werden nicht berücksichtigt.

Es gibt eine proposal Überlastung von operator. zu ermöglichen, um genau das zu ermöglichen, was Sie wollen, aber das wird nicht Standard bis mindestens C++ 17 sein, wenn überhaupt.

-1

Dies ist eine Sprachbeschränkung, wie @MikeSeymour darauf hingewiesen hat.

Und das ist der Grund, warum ich denke, std::reference_wrapper sollte eine überladene operator& haben, die die Adresse des verpackten Objekts zurückgibt:

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

Damit später kann man &Foo->f() oder (*&Foo).f() statt Foo.get().f() oder static_cast<T&>(Foo).f() verwenden.