【问题标题】:C++ boost::spirit::karma rule for variants变体的 C++ boost::spirit::karma 规则
【发布时间】:2014-10-10 19:02:46
【问题描述】:

我的程序中有一个boost::variant,它采用doubleuint16_tstd::string 等类型。我正在存储这些,我想使用boost::karma 来生成/打印它们出去。我是 boost::spirit 的新手,但我知道它适用于变体。我有什么选择呢?生成其中一个的简单语法/规则是什么样的?任何帮助都会很棒!

【问题讨论】:

    标签: c++ boost boost-spirit boost-variant boost-spirit-karma


    【解决方案1】:

    1。简单规则

    我能想到的绝对最简单的例子,展示了 karma 如何为您的特定变体即时合成 auto_ 规则[1] :

    #include <boost/spirit/include/karma.hpp>    
    namespace karma = boost::spirit::karma;
    
    int main() {
        typedef boost::variant<double, unsigned int, std::string> V;
    
        for(auto v : { V{42u}, V{3.1416}, V{"Life Of Pi"} })
            std::cout << karma::format(karma::auto_, v) << "\n";
    }
    

    打印:

    42
    3.142
    Life Of Pi
    

    简单易行!

    单独语法中的等价物:Live On Coliru

    2。一个更复杂的样本

    一个更复杂的语法(也是Live On Coliru),它向您展示了 Spirit 的属性兼容性如何神奇地规则 DoTheRightThing™:

    #include <boost/spirit/include/karma.hpp>
    
    namespace karma = boost::spirit::karma;
    
    typedef boost::variant<double, unsigned int, std::string> V;
    
    struct gen : karma::grammar<boost::spirit::ostream_iterator, V()> {
        gen() : gen::base_type(start) 
        {
            using namespace karma;
    
            start = my_real | my_uint | my_text;
    
            my_uint = "The value is unsigned integral value (" << uint_ << ")";
            my_real = "The value is double precision floating point value (" << double_ << ")";
            my_text = "The value is an epos: '" << *quoted_char << "'";
    
            quoted_char = '\\' << char_("'") | graph | "\\x" << uint_generator<uint8_t, 16>();
        }
      private:
        karma::rule<boost::spirit::ostream_iterator, V()>           start;
        karma::rule<boost::spirit::ostream_iterator, double()>      my_real;
        karma::rule<boost::spirit::ostream_iterator, unsigned       int()>   my_uint;
        karma::rule<boost::spirit::ostream_iterator, std::string()> my_text;
        karma::rule<boost::spirit::ostream_iterator, uint8_t()>     quoted_char;
    };
    
    int main()
    {
        for(auto v : { V{42u}, V{3.1416}, V{"It's a beautiful day!"} })
            std::cout << karma::format(gen(), v) << "\n";
    }
    

    打印出来:

    The value is unsigned integral value (42)
    The value is double precision floating point value (3.142)
    The value is an epos: 'It\'s\x20a\x20beautiful\x20day!'
    

    main也可以写成

    int main() {
        std::cout << karma::format(gen() % "\n", std::vector<V>{42u,3.1416,"It's a beautiful day!"}) << "\n";
    }
    

    这应该让您了解 Spirit Parser/Generator 框架的多功能性。


    [1] 只要存在自动解析器生成器特征; Spirit 为它们提供了多种类型,包括uintstd::stringdoublevariant(还包括可选项、向量、映射、任何可以改编为 Fusion 序列等的东西等)

    【讨论】:

    • 添加了一些不错的示例。我很确定这应该对您有所帮助:) Live On Coliru
    • 非常感谢您的富有洞察力的回复!这对我帮助很大!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    相关资源
    最近更新 更多