【问题标题】:how to increase the number of types that can handled by boost::variant如何增加 boost::variant 可以处理的类型数量
【发布时间】:2016-04-14 15:28:49
【问题描述】:

我正在为 verilog 语言设计一个解析器,其中一个规则有 25 个组件,我需要一个很大的 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>

但是错误依旧存在,

【问题讨论】:

    标签: c++ boost variant boost-variant


    【解决方案1】:

    c++98 模式下的 clang++ 和 g++ 中的错误(您似乎得到的)非常短(遗憾的是没用)。 在 c++11 中,错误更大,并揭示了关键问题:

    错误:类模板“列表”的模板参数过多
    typedef typename mpl::list::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

    【讨论】:

    • 我在寻找答案的时候读过这个,但我发现它来自 mpl,而不是变体。但无论如何,它有效,非常感谢。
    • 但是编译速度明显变慢了,有什么建议吗?
    • 我没有这方面的经验,但我认为this question 可能会有所帮助。不幸的是,直到今晚(从现在起超过 12 小时)我才能对其进行测试。另一个可能的建议是尝试简化变体,例如使用嵌套的 declarationinstantiationconstruct 变体(如果它们在您的模型中有意义)。
    • 我已恢复使用最大 20 类型的标准 boost::variant,并且我将大型变体分解为 2 个较小的变体以适应 20 的界限。编译改进了大约 3 倍。
    【解决方案2】:

    我也偶然发现了同样的问题。不幸的是,我无法使用上面的解决方案,因为我依赖于已经使用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 类型的列表(类似于线性列表)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多