Boost Spirit x3元组构造和隐式used_type

时间:2018-07-07 21:28:36

标签: c++ boost-spirit boost-spirit-x3

在阅读文档时,我认为以下内容应该可以正常工作,但是除非我不将输出传递给phrase_parse调用,否则它将无法编译,在这种情况下,它可以正常工作,尽管我无法获得我想要的数据。看来nvp_def的类型为(string, unused_type, uin32_t)(在我阅读文档时)会按照我的期望创建一个元组,但是显然并非如此。我缺少什么才能获取解析数据?

#include <boost/spirit/home/x3.hpp>
#include <tuple>
namespace x3 = boost::spirit::x3;

x3::rule<class idtype, std::string> const idrule = "idrule";
auto const idrule_def = x3::lexeme[+x3::char_("a-zA-Z0-9")];

x3::rule<class nvp, std::tuple<std::string, uint32_t>> const nvp = "nvp";
auto const nvp_def = idrule >> x3::char_(':') >> x3::hex;

BOOST_SPIRIT_DEFINE(idrule, nvp);

int main(int argc, char *argv[])
{
    std::tuple<std::string, uint32_t> output;

    const std::string total =  "foo4bar:deadbeef";
    std::string::const_iterator first = total.begin();
    std::string::const_iterator const last = total.end();

    bool r = x3::phrase_parse(first, last, nvp, x3::space, output);
}

编译错误(尝试将uint32_t从十六进制分配给元组):

/usr/include/boost/spirit/home/x3/support/traits/move_to.hpp:62: error: no match for ‘operator=’ (operand types are ‘std::tuple<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int>’ and ‘std::remove_reference<unsigned int&>::type {aka unsigned int}’)
         dest = std::move(src);
         ~~~~~^~~~~~~~~~~~~~~~

1 个答案:

答案 0 :(得分:1)

您缺少的主要问题包括:<boost/fusion/include/std_tuple.hpp>;如果没有此适配器std::tuple,则不是有效的Fusion sequence,因此Spirit无法使用它来存储复合属性。 (注:您的示例也缺少<string><stdint.h>。)

您的第二个问题是x3::char_具有属性,但是您不希望定界冒号具有属性,因此nvp_def应该是idrule >> ':' >> x3::hexidrule >> x3::lit(':') >> x3::hex。还要注意,x3::hex的实际属性是unsigned,因此使用uint32_t字段存储它可能会在某些平台上截断。