2016-01-10 47 views
8

我正在设计一个verilog语言的解析器,其中一个规则有25个组件,我需要一个大的boost :: variant来保存它:如何增加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

在铛++和g ++在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小时)。另一个可能的建议是尝试简化变体,例如,如果它们在模型中有意义,则使用嵌套的'declaration','instantiation'和'construct'变体。 – llonesmiz

0

我也是偶然发现了同样的问题。不幸的是,我无法使用上面的解决方案,因为我依赖于已使用boost-variant#define BOOST_MPL_LIMIT_LIST_SIZE 20的其他库。重新编译boost-variant库waws对我来说也不是理想的解决方案。

因此,我为我的问题设计了一个解决方法。下面的代码用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类型的列表(类似于线性列表)。

相关问题