2016-01-10 40 views
8

Projektuję parser dla języka verilog, a jedna z reguł ma 25 składników, których potrzebuję dużego boost :: wariant do przechowywania:jak zwiększyć liczbę typów, które mogą być obsługiwane przez boost :: wariant

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 ; 

Ale g ++ narzeka, że ​​wariant boost :: może pomieścić nie więcej niż 20 typów.

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; 

I stara się przedefiniować BOOST_VARIANT_LIMIT_TYPES do większej wartości:

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

ale błąd nadal istnieje,

Odpowiedz

7

Błędy w Clang ++ i g ++ w C++ 98 MODE (co wydajesz uzyskać) są dość krótkie (i niestety bezużyteczne). w C++ 11 błędu są większe i sposób odsłonić kluczową problem:

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

Jeśli spojrzeć w Boost.MPL documentation widać, że trzeba dodać:

#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS 
#define BOOST_MPL_LIMIT_LIST_SIZE 30 

można wykonywać tylko lista ma domyślnie rozmiar 30, 40 lub 50, jeśli chcesz więcej, musisz wygenerować własne nagłówki.

Running on Coliru

+0

Przeczytałem ten podczas wyszukiwania odpowiedzi, ale uważam, że jest z mpl, a nie wariant. Ale w każdym razie to działa, dziękuję bardzo. – shengyushen

+0

Ale kompilacja spowalnia znacznie, wszelkie sugestie? – shengyushen

+0

Nie mam doświadczenia z tym, ale myślę, że [to pytanie] (http://stackoverflow.com/q/19493630/2417774) może pomóc. Niestety nie będę mógł go przetestować aż do dzisiejszej nocy (ponad 12 godzin od teraz). Inną możliwą sugestią może być próba uproszczenia wariantu, na przykład za pomocą zagnieżdżonych wariantów 'declaration',' instanceiation' i 'construct', jeśli mają one sens w twoim modelu. – llonesmiz

0

ja również natknęliśmy się na ten sam problem. Niestety, nie mogę użyć powyższego rozwiązania, ponieważ jestem zależny od innych bibliotek, które już używają boost-variant z #define BOOST_MPL_LIMIT_LIST_SIZE 20. Ponowna kompilacja bibliotek boost-variant również nie jest dla mnie pożądanym rozwiązaniem.

W związku z tym opracowałem obejście mojego problemu. Poniższy kod ilustruje ideę tego obejścia z 39 typami.

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

Rozwiązanie to tworzy listę boost-variant typów (podobnej do listy liniowej).