2016-06-29 10 views
-1

Wie funktioniert das Templat-Operator() Arbeit in reference_wrapper Umsetzungreference_wrapper Implementierungsdetails

template <class T> 
class reference_wrapper { 
public: 
    // types 
    typedef T type; 

    // construct/copy/destroy 
    reference_wrapper(T& ref) noexcept : _ptr(std::addressof(ref)) {} 
    reference_wrapper(T&&) = delete; 
    reference_wrapper(const reference_wrapper&) noexcept = default; 

    // assignment 
    reference_wrapper& operator=(const reference_wrapper& x) noexcept = default; 

    // access 
    operator T&() const noexcept { return *_ptr; } 
    T& get() const noexcept { return *_ptr; } 

hier geht es:

template< class... ArgTypes > 
    typename std::result_of<T&(ArgTypes&&...)>::type 
    operator() (ArgTypes&&... args) const { 
    return std::invoke(get(), std::forward<ArgTypes>(args)...); 
    } 

warum brauchen wir operator() überhaupt? wie es funktioniert?

Wie lautet der Rückgabewert "result_of :: type"?

was ist (ArgTypes & & ..) ??

aufrufen (get) ???

dieser Code sieht aus wie C++ von einem anderen Planeten :)

private: 
    T* _ptr; 
}; 

Antwort

1

warum brauchen wir operator() überhaupt? wie es funktioniert?

Angenommen folgenden Zusammenhang

int foo(int bar) 
{ 
    return bar + 5; 
} 

int main() 
{ 
    std::reference_wrapper<int(int)> ref = foo; 
    ref(5); 
} 

ref(5) Anrufe operator() Referenz-Wrapper. Wenn es nicht da wäre, würde es nicht funktionieren, weil eine benutzerdefinierte Konvertierung in diesem Fall nicht stattfinden würde.

operator() gibt std::result_of<T&(ArgTypes&&...) zurück, das ist der Rückgabewert der gespeicherten Funktion und std::invoke rufen eine solche Funktion auf und leiten Parameter an sie weiter.

+0

oh wow, so kann nicht nur der Reference_wrapper Funktion kapseln, sondern auch mit einigen Vorlage Magie ist in der Lage, den Funktionsaufruf mit Vorlagen-Parameter-Weiterleitung auszudrücken? das ist erstaunlich! Wie haben Sie das gewußt? Über die std :: result_of, std :: invoke usw. Und wo kann ich etwas lernen? I.e. Ich meine das, wie ich vielleicht vermuten könnte, dass es erlaubt ist, eine Funktion zu umbrechen, oder sogar den Rückgabetyp mit dieser benutzerdefinierten Vorlage auszudrücken. Gibt es ein großes systematisches Handbuch? Oder sein "heiliges Wissen"? – barney

+0

@ barney ['std :: result_of'] (http://en.cppreference.com/w/cpp/types/result_of), [' std :: invoke'] (http://en.cppreference.com/ w/cpp/Dienstprogramm/funktional/invoke). Nicht nur diese Seite hat eine Erklärung der Standard-Klassen, es gibt in der Regel * Mögliche Implementierung * Abschnitt, wo Sie sehen können, wie es implementiert werden könnte und Sie können eine Menge daraus lernen. – Zereges