2014-01-17 47 views
1

我想调试一个简单的结构,它包含一个枚举类与BOOST_SPIRIT_DEBUG_NODE,但我总是得到编译错误“C:\ boost \ boost \ spirit \ home \ SUPPORT \ attributes.hpp:1226:错误:无法绑定 '的std :: basic_ostream' 左值到 '的std :: basic_ostream & &' 近 '了< < VAL;'”Boost精神调试枚举类(C++ 11)编译错误

我不知道为什么我得到这样的右值错误,我试图为运算符< <增加一个手动超载,但是这也不起作用。

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

当我将enum类更改为默认的C++枚举时,它可以工作,但我想使用新的枚举类进行适当的名称空间处理。

+0

仅仅因为编译器会列出'operator <<'的所有候选重载,你就会得到“像这样的rvalues”。 – sehe

回答

3

I don't know why I get a rvalue error like that, I tried to to add a manual overload for the operator<< for the enum class but that didn't work either.

我认为需要的代码,因为这确实工作:

  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; 
    } 
    

我的猜测是你忘了系列化添加到您的任何枚举你的结构。

+0

谢谢你的工作。我试图在结构体外定义运算符<<,但仍然得到相同的错误。我想我必须像frend一样使用它,但那很好。 :) – Xander

+1

@Xander你的问题,那么将是该运营商当时不可见。有两个原因:它是在相关实例之后声明的,或者是在定义'struct'或'enum class'的名称空间之外声明的。事实上,后者似乎对我来说很可能。 – sehe