2016-01-10 11 views
8

Sto progettando un parser per il linguaggio verilog, e una delle regole ha 25 componenti, che ho bisogno di un grande boost :: variante per tenerlo:come aumentare il numero di tipi che possono essere gestiti da boost :: variante

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 ; 

Ma g ++ si lamenta che la variante boost :: non può contenere più di 20 tipi.

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; 

ho cerca di ridefinire BOOST_VARIANT_LIMIT_TYPES al valore maggiore:

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

Ma l'errore è ancora lì,

risposta

7

Gli errori nel clangore ++ e g ++ nel modo C++ 98 (quello che ti sembra per ottenere) sono piuttosto brevi (e purtroppo inutili). in C++ 11 l'errore sono il modo più grande e rivelano il problema chiave:

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

Se si guarda nel Boost.MPL documentation si può vedere che è necessario aggiungere:

#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS 
#define BOOST_MPL_LIMIT_LIST_SIZE 30 

Si può solo fare l'elenco ha una dimensione 30, 40 o 50 di default, se vuoi di più devi generare intestazioni personalizzate.

Running on Coliru

+0

Ho letto questo quando cerco la risposta, ma trovo che è da mpl, non da variante. Ma comunque, funziona, grazie mille. – shengyushen

+0

Ma la compilazione rallenta in modo significativo, qualche suggerimento? – shengyushen

+0

Non ho esperienza con questo, ma penso che [questa domanda] (http://stackoverflow.com/q/19493630/2417774) potrebbe aiutare. Sfortunatamente non sarò in grado di testarlo fino a stasera (oltre 12 ore da ora). Un altro possibile suggerimento potrebbe essere quello di provare a semplificare la variante, ad esempio usando nested 'declaration',' instantiation' e 'construct' varianti se hanno senso nel modello. – llonesmiz

0

Ho anche capitati per lo stesso problema. Purtroppo, non sono in grado di utilizzare la soluzione di cui sopra, poiché sono dipendente da altre librerie che già utilizzano boost-variant con #define BOOST_MPL_LIMIT_LIST_SIZE 20. Anche la ricompilazione delle librerie boost-variant non è una soluzione desiderata per me.

Quindi, ho escogitato una soluzione alternativa per il mio problema. Il seguente codice illustra l'idea di questa soluzione alternativa con 39 tipi.

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; 
} 

La soluzione solo crea un elenco di boost-variant tipi (simile a una lista lineare).

Problemi correlati