2016-01-10 26 views
8

Ich entwerfe einen Parser für Verilog-Sprache, und eine der Regel haben 25 Komponenten, die ich brauche eine große boost :: Variante, um es zu halten:wie man die Anzahl der Typen erhöht, die boost :: variant behandeln kann

typedef boost::variant< 
shared_ptr<T_module_item__port_declaration> 
, shared_ptr<T_module_item__generate_region> 
, shared_ptr<T_module_item__specify_block> 
, shared_ptr<T_module_item__parameter_declaration> 
, shared_ptr<T_module_item__specparam_declaration> 
, shared_ptr<T_module_item__net_declaration> 
, shared_ptr<T_module_item__reg_declaration> 
, shared_ptr<T_module_item__integer_declaration> 
, shared_ptr<T_module_item__real_declaration> 
, shared_ptr<T_module_item__time_declaration> 
, shared_ptr<T_module_item__realtime_declaration> 
, shared_ptr<T_module_item__event_declaration> 
, shared_ptr<T_module_item__genvar_declaration> 
, shared_ptr<T_module_item__task_declaration> 
, shared_ptr<T_module_item__function_declaration> 
, shared_ptr<T_module_item__local_parameter_declaration> 
, shared_ptr<T_module_item__parameter_override> 
, shared_ptr<T_module_item__continuous_assign> 
, shared_ptr<T_module_item__gate_instantiation> 
, shared_ptr<T_module_item__udp_instantiation> 
, shared_ptr<T_module_item__module_instantiation> 
, shared_ptr<T_module_item__initial_construct> 
, shared_ptr<T_module_item__always_construct> 
, shared_ptr<T_module_item__loop_generate_construct> 
, shared_ptr<T_module_item__conditional_generate_construct> 
> module_item ; 

Aber g ++ beschweren, dass die boost :: Variante nur nicht mehr als 20 Arten halten kann.

verilogast.h|1129 col 2| error: wrong number of template arguments (25, should be 20) 
|| > module_item ; 
|| ^
/usr/include/boost/variant/variant_fwd.hpp|213 col 53| error: provided for ‘template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class T16, class T17, class T18, class T19> class boost::variant’ 
|| template <BOOST_VARIANT_AUX_DECLARE_PARAMS> class variant; 

ich versuche BOOST_VARIANT_LIMIT_TYPES zu größerem Wert neu zu definieren:

#define BOOST_VARIANT_LIMIT_TYPES 30 
#include<boost/variant.hpp> 

Aber der Fehler ist immer noch da,

Antwort

7

Die Fehler in Klirren ++ und g ++ in C++ 98-Modus (was Sie scheinen zu bekommen) sind ziemlich kurz (und leider nutzlos). in C++ 11 der Fehler sind viel größer und das Schlüsselproblem zeigen:

error: too many template arguments for class template 'list'
typedef typename mpl::list< T... >::type type;

Wenn Sie die Boost.MPL documentation aussehen in können Sie sehen, dass Sie hinzufügen müssen:

#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS 
#define BOOST_MPL_LIMIT_LIST_SIZE 30 

Sie nur machen können Die Liste hat standardmäßig die Größe 30, 40 oder 50. Wenn Sie mehr möchten, müssen Sie benutzerdefinierte Header generieren.

Running on Coliru

+0

Ich habe dieses bei der Suche nach Antwort gelesen, aber ich finde es ist von MPL, nicht Variante. Aber trotzdem funktioniert es, vielen Dank. – shengyushen

+0

Aber Kompilierung verlangsamt sich erheblich, irgendein Vorschlag? – shengyushen

+0

Ich habe keine Erfahrung damit, aber ich denke, [diese Frage] (http://stackoverflow.com/q/19493630/2417774) könnte helfen. Leider kann ich es erst heute Abend testen (ab 12 Stunden). Ein anderer möglicher Vorschlag könnte sein, zu versuchen, die Variante zu vereinfachen, zum Beispiel mit geschachtelten 'Deklaration'-, 'Instanziierungs'- und' Konstrukt'-Varianten, wenn sie in Ihrem Modell sinnvoll sind. – llonesmiz

0

stolperte ich auch auf das gleiche Problem. Leider kann ich die obige Lösung nicht verwenden, da ich von anderen Bibliotheken abhängig bin, die bereits boost-variant mit #define BOOST_MPL_LIMIT_LIST_SIZE 20 verwenden. Das Kompilieren der boost-variant Bibliotheken ist auch keine erwünschte Lösung für mich.

Daher habe ich eine Problemumgehung für mein Problem entwickelt. Der folgende Code veranschaulicht die Idee dieser Problemumgehung mit 39 Typen.

typedef boost::variant< 
    A<20>,A<21>,A<22>,A<23>,A<24>,A<25>,A<26>,A<27>,A<28>,A<29>,A<30>,A<31>,A<32>,A<33>,A<34>,A<35>,A<36>,A<37>,A<38>,A<39> 
> NextVar; 

typedef boost::variant< 
    A<1>,A<2>,A<3>,A<4>,A<5>,A<6>,A<7>,A<8>,A<9>,A<10>,A<11>,A<12>,A<13>,A<14>,A<15>,A<16>,A<17>,A<18>,A<19>,NextVar 
> TVar; 

struct PrintVisitor : public boost::static_visitor<std::string> { 
    result_type operator()(const NextVar& n) { 
     return n.apply_visitor(*this); 
    } 

    template<int T> 
    result_type operator()(const A<T>& a) { 
     return std::to_string(a.value); 
    } 
}; 

int main(int argc, char **args) { 
    TVar x = A<35>(); // Implicit conversion! Great! 
    PrintVisitor v; 
    std::cout << x.apply_visitor(v) << std::endl; 
} 

Die Lösung schafft nur eine Liste von boost-variant Typen (ähnlich einer linearen Liste).