c++ - Boost Spirit X3:将数据提取到 x3::variant<...> 始终为空

标签 c++ boost-spirit-x3

我想将一些输入解析为 longstd::string如果它被引用。合理的解决方案是使用 x3::variant<long, std::string>来存储数据。这是一个示例程序:

#include <iostream>
#include <string>

#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>

namespace x3 = boost::spirit::x3;

const x3::rule<class number_tag, long> number = "number";
const auto number_def = x3::long_;
BOOST_SPIRIT_DEFINE(number);

const x3::rule<class string_tag, std::string> string = "string";
const auto string_def = x3::lexeme['"' >> *(x3::char_ - '"') >> '"'];
BOOST_SPIRIT_DEFINE(string);

using any_type = x3::variant<long, std::string>;
const x3::rule<class any_tag, any_type> any = "any";
const auto any_def = number | string;
BOOST_SPIRIT_DEFINE(any);

int main()
{
    const std::string src = "18";
    any_type result;
    auto iter = src.begin();
    bool success = x3::phrase_parse(iter, src.end(), any, x3::space, result);
    if (!success || iter != src.end())
        return 1;
    else
        std::cout << "Result: " << result << std::endl;
}

我的预期结果是:

Result: 18

然而,实际结果很简单:

Result:

我做错了什么? Boost 版本为 1.61。

最佳答案

你不能像那样打印变体。您必须将其传递给访客。例如(没有为转换做太多错误检查):

struct Visitor
{
  using result_type = long;

  result_type operator()(long v) const { return v; }
  result_type operator() (const std::string& v) { return std::atol(v.c_str()); }
};

并且应该从您的代码中调用,例如:

    if (!success || iter != src.end()) {
        return 1;
    } else {
        Visitor v;
        std::cout << "Result: " << boost::apply_visitor(v, result) << std::endl;
    }

关于c++ - Boost Spirit X3:将数据提取到 x3::variant<...> 始终为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40477563/

相关文章:

c++ - 模板类型的限制

c++ - vs2017 输出错误但 mingw 有效

java - Android XML 等效于 C+ +'s "使用命名空间...”?

boost - 使用 Boost Spirit X3 编写解析器对 future 有多安全?

c++ - 阻止 X3 符号匹配子字符串

c++ - Spirit X3 可以搭配 BOOST_FUSION_ADAPT_ADT 使用吗?

c++ - 初始化的结构是不可变的吗?

c++ - 将 void 指针转换为结构时无法获取值

c++ - boost Spirit X3 中的上下文是什么?

c++ - 存储在变量模板特化中的 Spirit-X3 解析器不适用于 Clang