编译错误C++ +精神x3没有可行重载=,没有匹配函数调用MOVEITO

编译错误C++ +精神x3没有可行重载=,没有匹配函数调用MOVEITO,c++,boost-spirit-x3,C++,Boost Spirit X3,Michael Caisse就Spirit X3作了一次演讲:。我曾尝试将演示文稿转录为工作代码,但我有编译错误,其中包括没有可行的重载“=”和对“move_to”的匹配函数调用。我的短语解析最后一行定义是否正确?有没有明显的错误 #include <boost/config/warning_disable.hpp> #include <boost/spirit/home/x3.hpp> #include <boost/spirit/home/x3/support/

Michael Caisse就Spirit X3作了一次演讲:。我曾尝试将演示文稿转录为工作代码,但我有编译错误,其中包括没有可行的重载“=”和对“move_to”的匹配函数调用。我的短语解析最后一行定义是否正确?有没有明显的错误

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/container/stable_vector.hpp>    

#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <map>    

namespace client { namespace ast
    {
        namespace x3 = boost::spirit::x3;

        using string_t = std::string;
        using double_t = double;
        using float_t = double;
        using int_t = int64_t;
        using bool_t = bool;
        struct null_t {};

        class value;

        using object_t = std::map<std::string, value>;
        using object_member_t = object_t::value_type;
        using array_t = boost::container::stable_vector<value>;

        class value : public x3::variant<null_t, bool_t, string_t, int_t, double_t, object_t, array_t>
        {
        public:
            using value_type = value;
            using base_type::base_type;
            using base_type::operator=;
            value(null_t val = null_t{}) : base_type(val) {}
            value(char const* val)       : base_type(string_t(val)) {}

            template<typename T>
            value(T val, typename std::enable_if<std::is_floating_point<T>::value>::type) : base_type(double_t{val}) {}

            template<typename T>
            value(T val, typename std::enable_if<std::is_integral<T>::value::type>) : base_type(int_t{val}) {}

        };

        struct json_class;
        using json_type = x3::rule<json_class, value>;
        json_type const json = "json";
        BOOST_SPIRIT_DECLARE(json_type);

        // identifier_class id
        // identifier_type  type
        // identifier_def   rule def
        // identifier       the rule

        struct value_class;
        struct object_class;
        struct member_pair_class;
        struct array_class;

        using value_type = x3::rule<value_class, value>;
        using object_type = x3::rule<object_class, object_t>;
        using member_pair_type = x3::rule<member_pair_class, object_member_t>;
        using array_type = x3::rule<array_class, array_t>;

        value_type const value = "value";
        object_type const object = "object";
        member_pair_type const member_pair = "member_pair";
        array_type const array = "array";

        auto const append = [](auto& ctx){ _val(ctx) += _attr(ctx); };

        using uchar = unsigned char;

        x3::uint_parser<uchar, 16, 4, 4> const hex4 = {};

        auto push_esc = [](auto& ctx)
        {
            auto& utf8 = _val(ctx);
            switch (_attr(ctx))
            {
                case '"' : utf8 += '"';   break;
                case '\\': utf8 += '\\';  break;
                case '/' : utf8 += '/';   break;
                case 'b' : utf8 += '\b';  break;
                case 'f' : utf8 += '\f';  break;
                case 'n' : utf8 += '\n';  break;
                case 'r' : utf8 += '\r';  break;
                case 't' : utf8 += '\t';  break;
            }
        };

        auto push_utf8 = [](auto& ctx)
        {
            typedef std::back_insert_iterator<std::string> insert_iter;
            insert_iter out_iter(_val(ctx));
            boost::utf8_output_iterator<insert_iter> utf8_iter(out_iter);
            *utf8_iter++ = _attr(ctx);
        };

        auto const escape = ('u' > hex4)            [push_utf8]
                          | x3::char_("\"\\/bfnrt") [push_esc];

        auto const char_esc = '\\' > escape;

        auto const double_quoted = x3::lexeme[ '"' > *(char_esc) | (x3::char_("\x20\x21\x23-\x5b\x5d\x7e")) [append]  > '"' ];

        struct unicode_string_class;
        using unicode_string_type = x3::rule<unicode_string_class, std::string>;
        unicode_string_type const unicode_string = "unicode_string";
        auto const unicode_string_def = double_quoted;
        BOOST_SPIRIT_DEFINE(unicode_string);    

        auto const null_value = x3::lit("null") >> x3::attr(null_t{});
        x3::int_parser<int64_t> const int_ = {};
        x3::ascii::bool_type const bool_value = {};

        auto const object_def = x3::lit('{') >> -(member_pair % ',') >> x3::lit('}');    

        auto const member_pair_def = unicode_string >> ':' >> value;

        auto const array_def = x3::lit('[') >> -(value % ',') >> x3::lit(']');

        auto const value_def = null_value | bool_value | object | array | unicode_string
                             | x3::lexeme[!('+' | (-x3::lit('-') >> '0' >> x3::digit)) >> x3::int_ >> !x3::char_(".eE")]
                             | x3::lexeme[!('+' | (-x3::lit('-') >> '0' >> x3::digit)) >> x3::double_ ];

        BOOST_SPIRIT_DEFINE(value, object, member_pair, array);
    }
}    

int main(int argc, char **argv)
{

    namespace x3 = boost::spirit::x3;

    std::string storage; // We will read the contents here.    

    using boost::spirit::x3::ascii::space;
    std::string::const_iterator iter = storage.begin();
    std::string::const_iterator iter_end = storage.end();

    client::ast::object_t o;
    auto const grammar = client::ast::value;

    bool r = phrase_parse(iter, iter_end, grammar, space, o);
}

好吧,我不得不纠正不少错误/怪癖

我熨烫衣服的一部分是清理我通常不一样的东西。以下是工作结果:

我的g++5在执行ADL查找_attr和_val(如果不符合条件)时似乎遇到了问题。我不确定这是编译器的问题,还是什么问题。我刚才用了x3::_attr和x3::_val

规则def中有大量缺少的参数,使得规则难以阅读/检查。添加它们

unicode_字符串最终被破坏,请参见下文

从未使用int_解析器?呵呵。使用它:

号码解析不起作用。同时,它看起来过于复杂。我建议使用double|int|,其中double|使用严格的策略:

x3::real_parser<double, x3::strict_real_policies<double> > const double_ = {};
测试驾驶员的噪音可以小得多:

std::string storage = R"({ "check": [ 1,2,3, null, true ], "more": { "nested" : "values" } })";

client::ast::value o;
bool r = parse(storage.begin(), storage.end(), client::parser::json, o);
我删除了这个简单代码示例中没有实际使用的规则的嘈杂的_class/_type/_def舞蹈,任何没有递归使用的规则:value

使用BOOST_SPIRIT_X3_DEBUG查看发生了什么:这使我能够发现X3::char\ux20\x21\x23-\x5b\x5d\x7e中的错误,是否看到缺少的破折号


我相信这段代码的一个版本也出现在github上:我在回答问题时没有使用它,请参阅,github上的自述文件提到了Spirit 2,而代码似乎没有x3标题。我把它放在XCode中,它可以编译,而且似乎工作得很好。我回来后会好好复习一下。非常感谢。丢失的连字符完全是我的错。谢谢你分享这个痛苦和有用的细节!对于boost 1.65.1和gcc 7.2,这将提供/boost/spirit/home/x3/nonterminal/detail/rule.hpp:316:24:错误:使用删除的函数'client::ast::value::valueconst client::ast::value&'value\u type make\u attr=make\u attribute::callattr;test14.cc:35:15:注意:“client::ast::value::valueconst client::ast::value&”隐式声明为已删除,因为“client::ast::value”声明了移动构造函数或移动赋值运算符类值:public x3::variant
using member_pair_t   = std::pair<object_t::key_type, object_t::mapped_type>;
x3::real_parser<double, x3::strict_real_policies<double> > const double_ = {};
auto const json = x3::skip(x3::ascii::space) [ value ];
std::string storage = R"({ "check": [ 1,2,3, null, true ], "more": { "nested" : "values" } })";

client::ast::value o;
bool r = parse(storage.begin(), storage.end(), client::parser::json, o);