Boost Spirit X3:将数据提取到 x3::variant<...> 始终为空
Boost Spirit X3: Extracting Data into x3::variant<...> is always empty
我想将某些输入解析为 long
或 std::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;
}
我想将某些输入解析为 long
或 std::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;
}