2016-01-10 1 views
8

Я разрабатываю парсер для языка verilog, и одно из правил содержит 25 компонентов, для которых мне нужен большой вариант boost :: для его удержания:Как увеличить количество типов, которые могут обрабатываться boost :: variant

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 ; 

Но g ++ жалуется, что boost :: variant может содержать не более 20 типов.

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; 

Я попытался переопределить BOOST_VARIANT_LIMIT_TYPES к большему значению:

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

Но ошибка все еще там,

ответ

7

Ошибки в звоне ++ и г ++ в C++ режима 98 (то, что вы, кажется, получить) довольно короткие (и, к сожалению, бесполезные). В C++ 11 ошибки являются способом больше и выявить ключевую проблему:

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

Если вы посмотрите в Boost.MPL documentation вы можете увидеть, что вам нужно добавить:

#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS 
#define BOOST_MPL_LIMIT_LIST_SIZE 30 

Вы можете только сделать список имеет размер 30, 40 или 50 по умолчанию, если вы хотите больше, вам придется создавать собственные заголовки.

Running on Coliru

+0

Я прочитал это при поиске ответа, но я нахожу, что это от mpl, а не от варианта. Но в любом случае, это работает, спасибо вам большое. – shengyushen

+0

Но компиляция значительно замедляется, любое предложение? – shengyushen

+0

У меня нет опыта с этим, но я думаю, что [этот вопрос] (http://stackoverflow.com/q/19493630/2417774) может помочь. К сожалению, я не смогу проверить его до сегодняшнего вечера (через 12 часов). Другое возможное предложение может заключаться в том, чтобы попытаться упростить вариант, например, используя варианты вложенного 'объявления',' instantiation' и 'construct', если они имеют смысл в вашей модели. – llonesmiz

0

я наткнулся на такой же проблемой. К сожалению, я не могу использовать решение выше, поскольку я зависим от других библиотек, которые уже используют boost-variant с #define BOOST_MPL_LIMIT_LIST_SIZE 20. Перекомпиляция библиотек boost-variant также не является желательным решением для меня.

Следовательно, я разработал обходной путь для своей проблемы. Следующий код иллюстрирует идею этого обходного пути с 39 типами.

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

Решение просто создает список boost-variant типов (по аналогии с линейным списком).

Смежные вопросы