2016-01-10 48 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類型的列表(類似於線性列表)。

相關問題