2016-05-11 21 views
0

Ich bin fest :). Ich habe eine zweistufige Hierarchie, jede Ebene hat untergeordnete Knoten. Ziel ist es, diese Struktur zu verwenden, um den Gui-Baum zu füllen. Ich versuche auf Kindknoten von varianten Mitgliedern in einer allgemeinen Weise zuzugreifen. Der folgende Code kompiliert nicht mit vs2013. Ich schätze die helfende Hand und/oder rate über die Designänderungen.Boost :: Variante - Get Vektor Eigenschaft der Mitglieder

#include "stdafx.h" 
#include <memory> 
#include <string> 
#include <vector> 
#include <boost/variant.hpp> 

class base {}; 

class A : public base 
{ 
public: 
    std::vector<std::shared_ptr<base>> & lst(){ return _lst; } 
private: 
    std::vector<std::shared_ptr<base>> _lst; 
}; 

class B : public base 
{ 
public: 
    std::vector<std::shared_ptr<A>>& lst() { return _lst; } 
private: 
    std::vector<std::shared_ptr<A>> _lst; 
}; 

using bstvar = boost::variant<A, B>; 

class lstVisitor : public boost::static_visitor<> 
{ 
public: 
    template <typename T> std::vector<std::shared_ptr<base>>& operator() (T& t) const 
    { 
     return t.lst(); 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    bstvar test; 
    auto& lst= boost::apply_visitor(lstVisitor{}, test); 

    return 0; 
} 

Antwort

0

Ihr Besucher hat einen impliziten Rückgabetyp void (das Template-Argument fehlt).

Hier ist die Gelegenheit nutzen, die Basisklasse zu entfernen, da es nicht mehr benötigt in den meisten c Basen ++ 11 Code:

Live On Coliru

#include <memory> 
#include <string> 
#include <vector> 
#include <boost/variant.hpp> 

class base {}; 

using base_vec = std::vector<std::shared_ptr<base> >; 

class A : public base { 
    public: 
    base_vec &lst() { return _lst; } 

    private: 
    base_vec _lst; 
}; 

class B : public base { 
    public: 
    base_vec &lst() { return _lst; } 

    private: 
    base_vec _lst; 
}; 

using bstvar = boost::variant<A, B>; 

struct lstVisitor { 
    using result_type = base_vec&; 
    template <typename T> result_type operator()(T &t) const { return t.lst(); } 
}; 

int main(int argc, char *argv[]) { 
    bstvar test { B{} }; 
    base_vec& lst = boost::apply_visitor(lstVisitor{}, test); 

    return 0; 
} 
+0

Vielen Dank! Frage zu Ihrem Kommentar: Sie haben den Rückgabeparameter von lst() in std :: vector > Klasse B im Beispiel hat diese Liste zurück Vektoren gemeinsamer Zeiger auf A. Ich sehe nicht Wie kann ich den Typ der Elemente im Container bestimmen, wenn Zeiger auf die Basisklasse zurückgibt. –

+0

Huh. 'operator()' gibt dies klar zurück. Wenn Sie darauf bestehen, können Sie nur eine Kopie konvertieren und zurückgeben ...: [demo] (http://coliru.stacked-crooked.com/a/2611392cee514d8e). Inzwischen denke ich, dass Sie sich entscheiden müssen: Wofür brauchen Sie statischen Polymorphismus und warum wollen Sie dynamischen Polymorphismus? – sehe

+0

Letzteres hat nichts mit variant zu tun: siehe ['dynamic_cast'] (http://en.cppreference.com/w/cpp/language/dynamic_cast) und [' dynamic_pointer_cast'] (http: //en.cppreference. com/w/cpp/speicher/shared_ptr/pointer_cast). Wenn Sie unterschiedliche Rückgabetypen benötigen, können Sie auch keinen einzelnen Besucher haben. Sie können natürlich zurückkehren ... eine andere Variante (uhoh): ** [so] (http://coliru.stacked-crooked.com/a/5e87a1b585a59fab) ** aber das scheint wie ein einigermaßen großer [Code Geruch] (https://en.wikipedia.org/wiki/Code_smell) zu mir. – sehe

Verwandte Themen