2014-01-17 41 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