2014-12-20 14 views
6

Ich versuche, ein Programm eine Möglichkeit zum Hinzufügen neuer Objekte zu einer Variante in einer Bibliothek zur Verfügung stellen, aber ich stoße auf einige kryptische Fehler.Erweitern Boost-Variante mit einer MPL-Liste

#include <boost/mpl/copy.hpp> 
#include <boost/mpl/joint_view.hpp> 
#include <boost/mpl/list.hpp> 
#include <boost/variant/variant.hpp> 

struct InternalType1 {}; 
struct InternalType2 {}; 

template <typename LocalTypes> 
struct Foo 
{ 
    typedef boost::mpl::list< 
    InternalType1, 
    InternalType2 
    > Types; 

    typename boost::make_variant_over< 
    typename boost::mpl::joint_view< 
     Types, 
     LocalTypes 
    >::type 
    >::type container_; 

    // typename boost::make_variant_over< 
    // typename boost::mpl::copy< 
    //  LocalTypes, 
    //  boost::mpl::back_inserter<Types> 
    // >::type 
    // >::type container_; 
}; 

struct LocalType1 {}; 
struct LocalType2 {}; 

int main() 
{ 
    typedef boost::mpl::list< 
    LocalType1, 
    LocalType2 
    > Types; 

    Foo<Types> foo; 
} 

Durch ein mpl::joint_view mit (was ich nehme an, wenn der effizienteste Weg, um dies zu erreichen), erhalte ich folgende Fehlermeldung:

/usr/local/include/boost/mpl/clear.hpp:29:7: error: implicit instantiation of undefined template 

von dem anderen Versuch uncommenting, mit mpl::copy, und es ersetzen mit den ursprünglichen, dann den Fehler Änderungen:

/usr/local/include/boost/mpl/aux_/push_back_impl.hpp:40:9: error: no matching function for call to 'assertion_failed' 

Welche interessanter~~POS=TRUNC hat die following comment:

Keiner dieser Fehler macht mir einen Sinn, denn ich sehe nicht, welche Vorlagen nicht vollständig sind und für die zweite, welche push_back-Spezialisierung verwende ich nicht?

+1

Das zweite ist recht einfach zu verstehen, [ ' mpl :: list'] (http://www.boost.org/libs/mpl/doc/refmanual/list.html) kann nicht mit 'push_back' verwendet werden. Sie können 'boost :: mpl :: front_inserter ' verwenden oder einfach einen 'mpl :: vector' in Ihrem' Typ' typedef verwenden. – llonesmiz

+0

Aaaah, ja, das war's. Vielen Dank! Ich werde die Frage offen lassen, weil die Lösung von joint_view wahrscheinlich die bessere ist oder die zwei, die in der Produktion zu tun sind. –

+0

Ich sehe keinen besseren Weg, wenn Sie 'make_variant_over' nicht ändern wollen. 'mpl :: copy' von 'mpl :: vector's ist der Weg, wenn Sie mich fragen – sehe

Antwort

2

Das Problem ist, dass boost::mpl::clear<> nicht für ein joint_view ... daher auch das große Compiler-Dump endet mit implementiert:

/usr/local/include/boost/mpl/clear.hpp:29:7: error: implicit instantiation of undefined template 'boost::mpl::clear_impl<boost::mpl::aux::joint_view_tag>::apply<boost::mpl::joint_view<boost::mpl::list<InternalType1, InternalType2, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, boost::mpl::list<LocalType1, LocalType2, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na> > >' 

(ich weiß nicht, wie das richtig zu formatieren)

Diese könnte nur ein Versehen in der Bibliothek sein, oder es ist einfach nicht klar , die leeren Sequenztyp sollte in diesem Fall zurückgegeben werden. Wenn Sie eine joint_view verwenden möchten, finden Sie eine Spezialisierung von clear_impl irgendwo bieten müssen:

namespace boost { namespace mpl { 
    template <> 
    struct clear_impl<aux::joint_view_tag> 
    { 
     template <typename JV> 
     struct apply { 
      typedef list<> type; // since you're using list I figured 
           // I would too. 
     }; 
    }; 
} } 

Damit kompiliert den Code für mich sowohl auf gcc und Klirren.

Alternativ kann, wenn das Hinzufügen Sachen in namespace boost::mpl Sie sich als wenig zwielichtig trifft aber Sie wollen immer noch mit list s halten, können Sie einfach insert_range verwenden:

typename boost::make_variant_over< 
    typename boost::mpl::insert_range< 
     Types, 
     typename boost::mpl::end<Types>::type, 
     LocalTypes 
    >::type 
>::type container_; 
+0

Das scheint es zu sein, danke! Ich denke, wenn man das in den Kontext einbezieht, klingen 'mpl :: copy' und' mpl :: vector' wirklich wie die beste Wahl. Wie du gesagt hast, macht ein leeres 'mpl :: joint_view' keinen Sinn ... –

+1

@SamKellett Kann tatsächlich die gleiche' insert_range' Metafunktion mit 'vector' verwenden. So oder so, am Ende hast du dasselbe. – Barry

Verwandte Themen