变体的 C++ boost::spirit::karma 规则

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

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

最佳答案

1。简单规则

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

#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(但还有可选值、 vector 、映射、任何可以改编为 fusion 序列的东西等等。)

关于变体的 C++ boost::spirit::karma 规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26306316/

相关文章:

c++ - 无法将简单的读/写串行端口代码从 boost::asio::serial_port 迁移到 QSerialPort

c++ - Visual Studio 2012 C++ 使用 Boost Signal2 编译错误

c++ - CMake:尝试将链接库添加到未在此目录中构建的目标

c++11 - 如何定义此提升精神规则的AST?

c++ - 如何使用 boost::spirit::qi::parse 从字符数组中解析 double

c++ - 如何使用 Poco C++ 库从数据库中读取 "dates"

c++ - std::make_pair 自动类型推导?

c# - C# 中从指定类型继承的模板类的等价物是什么?

c++ - 线程池适合生产吗?如果没有,是否有任何替代库?

c++ - 提升精神宽字符规则创建空字符