2017-02-01 2 views
0

Ich habe online nach einer Möglichkeit suchen, eine perfekte und effiziente Umleitung (Proxy) zu einem Mitglied-Objekt zu tun. Aber ich kann keine nützliche Ressource finden. Ich stelle mir vor, das ist eine Aufgabe, die Programmierer oft (manchmal schlecht) machen, und es könnte ein gutes Wissen sein, einen guten, effizienten und prägnanten (minimalistischen) Weg zu kennen.C++ perfekte Weiterleitung/Proxy von gekapselten Mitglied

Ich möchte Ihren Rat zu wissen, ob mein Verständnis von Verschiebeoperationen richtig ist und ob dieser Proxy insbesondere für Kopieren und Verschieben von Konstruktor/Zuweisungsoperatoren korrekt ist.

Um eine perfekte Weiterleitung in einem Move Konstruktor/Zuweisung Operator mein Verständnis ist, dass wir std::move verwenden, wenn wir sicher sind, dass wir eine lvalue an das gekapselte Objekt und std::forward andernfalls übergeben. Ist es richtig?

Hier ist mein Code

#include <boost/variant.hpp> 

/* ********************************************************************/ 
// Class 
/* ********************************************************************/ 
template <class... T> 
class BoostVariantWrapper { 

     /* ********************************************************************/ 
     // Private fields 
     /* ********************************************************************/ 
     boost::variant<T...> variant; 

    public: 

     /* ********************************************************************/ 
     // Constructors/Destructors 
     /* ********************************************************************/ 
     BoostVariantWrapper() {} 

     BoostVariantWrapper(const BoostVariantWrapper &other) : 
     BoostVariantWrapper(other.variant) 
     {} 

     BoostVariantWrapper(BoostVariantWrapper &other) : 
     BoostVariantWrapper(other.variant) 
     {} 

     BoostVariantWrapper(BoostVariantWrapper &&other) : 
     BoostVariantWrapper(std::move(other.variant)) 
     {} 

     template<class TOther> 
     BoostVariantWrapper(TOther &&other) : 
     variant(std::forward<TOther>(other)) 
     {} 

     /* ********************************************************************/ 
     // Public methods 
     /* ********************************************************************/ 
     template <class U> 
     U& get() { 
      return boost::get<U>(variant); 
     } 

     template <class Fn> 
     inline void applyVisitor(Fn&& visitor) { 
      boost::apply_visitor(std::forward<Fn>(visitor), variant); 
     } 

     template <class Fn> 
     inline void applyVisitor(Fn&& visitor) const { 
      boost::apply_visitor(std::forward<Fn>(visitor), variant); 
     } 

     /* ********************************************************************/ 
     // Operators 
     /* ********************************************************************/ 
     BoostVariantWrapper& operator=(const BoostVariantWrapper &other) { 
      return operator=(other.variant); 
     } 

     BoostVariantWrapper& operator=(BoostVariantWrapper &other) { 
      return operator=(other.variant); 
     } 

     BoostVariantWrapper& operator=(BoostVariantWrapper &&other) { 
      return operator=(std::move(other.variant)); 
     } 

     template<class TOther> 
     BoostVariantWrapper& operator=(TOther &&other) { 
      variant = std::forward<TOther>(other); 
      return *this; 
     } 

     bool operator==(const BoostVariantWrapper &other) const { 
      return variant == other.variant; 
     } 

     bool operator<(const BoostVariantWrapper &other) const { 
      return variant < other.variant; 
     } 

     friend std::ostream& operator<<(std::ostream &os, const BoostVariantWrapper &x) { 
      os << x.variant; 
      return os; 
     } 

     /* ********************************************************************/ 
     // Serialization 
     /* ********************************************************************/ 
     template<class Archive> 
     void serialize(Archive &ar, const unsigned int) { 
      ar & variant; 
     } 
}; 

Edited basierend auf Kommentar von Jarod42

+0

Schrecklicher Kommentar Stil. Ein großer Kommentar 'class' vor der Klassendefinition macht Code sicher lesbarer! Was den Kern der Frage betrifft, bin ich mir nicht sicher, wonach Sie fragen. Perfektes Weiterleiten und Bewegen sind zwei unabhängige Konzepte. – SergeyA

+0

Für funktionierenden Code, http://codereview.stackexchange.com/ könnte besser geeignet sein. – Jarod42

+0

Es scheint, dass einige Überladungen nicht benötigt werden, sonst sehe ich keinen Fehler (fehlt 'std :: forward' für Besucher btw). – Jarod42

Antwort

0

std :: Vorwärts selbst tut perfekt Forwarding. Es ist für diesen Zweck gedacht.