Boost Spirit调试枚举类(c ++ 11)编译错误

时间:2014-01-17 15:38:56

标签: boost c++11 enums boost-spirit boost-spirit-qi

我正在尝试调试一个包含带有BOOST_SPIRIT_DEBUG_NODE的枚举类的简单结构,但我总是得到编译错误“C:\ boost \ boost \ spirit \ home \ support \ attributes.hpp:1226:错误:无法绑定'std :: basic_ostream'左值'std :: basic_ostream&&'靠近'out<< val;'“

我不知道为什么会出现这样的rvalue错误,我试图为运算符添加手动重载<<对于枚举类,但这也不起作用。

我正在使用boost 1.55并尝试使用gcc 4.8在Windows 8.1 x64上使用MinGW 32位进行编译。

当我将枚举类更改为默认的c ++枚举时,它可以工作,但我想使用新的枚举类来进行正确的命名空间处理。

1 个答案:

答案 0 :(得分:3)

  

我不知道为什么会出现这样的rvalue错误,我试图为运算符添加手动重载<<对于枚举类,但这也不起作用。

我认为需要代码,因为 工作:

  1. 首先,使用经典枚举 Live on Coliru

    #define BOOST_SPIRIT_DEBUG
    #include <boost/spirit/include/qi.hpp>
    #include <iostream>
    
    namespace qi    = boost::spirit::qi;
    
    struct data_t
    {
        std::string label;
        enum Choice { left, right, up, down } choice;
    
        data_t(std::string label="default", Choice choice=left): label(std::move(label)), choice(choice) {}
    
        friend std::ostream& operator<<(std::ostream& os, Choice const& v) {
            switch(v) { 
                case left: return os << "left";
                case right:return os << "right";
                case up:   return os << "up";
                case down: return os << "down";
                default:   return os << "?";
            }
        }
        friend std::ostream& operator<<(std::ostream& os, data_t const& v) {
            return os << "{label:" << v.label << ";choice:" << v.choice << "}";
        }
    };
    
    
    template <typename It, typename Skipper = qi::space_type>
        struct parser : qi::grammar<It, data_t(), Skipper>
    {
        parser() : parser::base_type(start)
        {
            using namespace qi;
    
            choice_.add
                ("left",  data_t::left)
                ("right", data_t::right)
                ("up",    data_t::up)
                ("down",  data_t::down);
    
            start %= as_string[ lexeme[+graph] ] >> lexeme [choice_];
    
            BOOST_SPIRIT_DEBUG_NODE(start);
        }
    
    private:
        qi::symbols<char, data_t::Choice> choice_;
        qi::rule<It, data_t(), Skipper> start;
    };
    
    bool doParse(const std::string& input)
    {
        typedef std::string::const_iterator It;
        auto f(begin(input)), l(end(input));
    
        parser<It, qi::space_type> p;
        data_t data;
    
        try
        {
            bool ok = qi::phrase_parse(f,l,p,qi::space,data);
            if (ok)   
            {
                std::cout << "parse success\n";
                std::cout << "data: " << data << "\n";
            }
            else      std::cerr << "parse failed: '" << std::string(f,l) << "'\n";
    
            if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
            return ok;
        } catch(const qi::expectation_failure<It>& e)
        {
            std::string frag(e.first, e.last);
            std::cerr << e.what() << "'" << frag << "'\n";
        }
    
        return false;
    }
    
    int main()
    {
        bool ok = doParse("label1 up");
        return ok? 0 : 255;
    }
    
  2. 其次是枚举类 Live on Coliru

    #define BOOST_SPIRIT_DEBUG
    #include <boost/spirit/include/qi.hpp>
    #include <iostream>
    
    namespace qi    = boost::spirit::qi;
    
    struct data_t
    {
        std::string label;
        enum class Choice { left, right, up, down } choice;
    
        data_t(std::string label="default", Choice choice=Choice::left): label(std::move(label)), choice(choice) {}
    
        friend std::ostream& operator<<(std::ostream& os, Choice const& v) {
            switch(v) { 
                case Choice::left: return os << "left";
                case Choice::right:return os << "right";
                case Choice::up:   return os << "up";
                case Choice::down: return os << "down";
                default:   return os << "?";
            }
        }
        friend std::ostream& operator<<(std::ostream& os, data_t const& v) {
            return os << "{label:" << v.label << ";choice:" << v.choice << "}";
        }
    };
    
    
    template <typename It, typename Skipper = qi::space_type>
        struct parser : qi::grammar<It, data_t(), Skipper>
    {
        parser() : parser::base_type(start)
        {
            using namespace qi;
    
            choice_.add
                ("left",  data_t::Choice::left)
                ("right", data_t::Choice::right)
                ("up",    data_t::Choice::up)
                ("down",  data_t::Choice::down);
    
            start %= as_string[ lexeme[+graph] ] >> lexeme [choice_];
    
            BOOST_SPIRIT_DEBUG_NODE(start);
        }
    
    private:
        qi::symbols<char, data_t::Choice> choice_;
        qi::rule<It, data_t(), Skipper> start;
    };
    
    bool doParse(const std::string& input)
    {
        typedef std::string::const_iterator It;
        auto f(begin(input)), l(end(input));
    
        parser<It, qi::space_type> p;
        data_t data;
    
        try
        {
            bool ok = qi::phrase_parse(f,l,p,qi::space,data);
            if (ok)   
            {
                std::cout << "parse success\n";
                std::cout << "data: " << data << "\n";
            }
            else      std::cerr << "parse failed: '" << std::string(f,l) << "'\n";
    
            if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n";
            return ok;
        } catch(const qi::expectation_failure<It>& e)
        {
            std::string frag(e.first, e.last);
            std::cerr << e.what() << "'" << frag << "'\n";
        }
    
        return false;
    }
    
    int main()
    {
        bool ok = doParse("label1 up");
        return ok? 0 : 255;
    }
    
  3. 我猜您忘记将序列化添加到您的enum 您的结构中。