2011-10-22 71 views
1

也比不上我有以下簡單的拉姆達默認構造右值

auto end_current_token = [&] { 
    if (current != Token()) { 
     tokens.push_back(current); 
     current = Token(); 
     cp = Codepoint(); 
    } 
}; 

其中currentToken類型,並提供操作員。但編譯器給出了一個奇怪的錯誤:

1>Lexer.cpp(6): error C2273: 'function-style cast' : illegal as right side of '->' operator 

這是什麼問題?

編輯:很多我想說,這不是所有相關的代碼,它是。除了隱含在this之外,在整個程序中沒有一次單獨使用 - >,並且錯誤消息清楚地指向已發佈的lambda。但是,由於它太小,我會發布所有的代碼。

#include <fstream> 
#include <string> 
#include <iostream> 
#include <vector> 
namespace Wide { 
    class Lexer { 
     struct Codepoint { 
      Codepoint() { 
       column = 0; 
       line = 0; 
       cp = 0; 
      } 
      int column; 
      int line; 
      wchar_t cp; 
      bool operator==(wchar_t other) { 
       return cp == other; 
      } 
     }; 
     enum TokenType { 
      IDENTIFIER, 
     }; 
     struct Token { 
      Token() 
       : line(0) 
       , columnbegin(0) 
       , columnend(0) {} 
      Token(const Codepoint& cp) { 
       *this = cp; 
      } 
      bool operator!=(const Token& other) { 
       return !(line == other.line && columnbegin == other.columnbegin && columnend == other.columnend); 
      } 
      Token& operator+=(const Codepoint& cp) { 
       if (cp.column >= columnend) 
        columnend = cp.column; 
       if (columnbegin == 0) 
        columnbegin = cp.column; 
       Codepoints += cp.cp; 
       if (line == 0) 
        line = cp.line; 
      } 
      Token& operator=(const Codepoint& cp) { 
       line = cp.line; 
       columnbegin = cp.column; 
       columnend = cp.column; 
       Codepoints = cp.cp; 
      } 

      int line; 
      int columnbegin; 
      int columnend; 
      TokenType type; 
      std::wstring Codepoints; 
     }; 
     struct FileStreamer { 
      int current; 
      std::vector<Codepoint> codepoints; 
      int line; 
      int column; 
      std::wifstream file; 
      FileStreamer(std::wstring filename) 
      : file(filename, std::ios::in | std::ios::binary) { 
       line = 0; 
       column = 0; 
       current = 0; 
       // Extract all the codepoints immediately. 
       Codepoint cp; 
       while(*this >> cp) 
        codepoints.push_back(cp); 
      } 
      operator bool() { 
       return current != codepoints.size(); 
      } 
      FileStreamer& operator>>(Codepoint& cp) { 
       if (*this) { 
        cp = codepoints[current]; 
        current++; 
       } 
       return *this; 
      } 
      void putback() { 
       if (current > 0) 
        current--; 
      } 
     }; 
     std::vector<Token> tokens; 
     FileStreamer stream; 
    public: 
     Lexer(std::wstring file) 
      : stream(file) {} 
     void operator()(); 
    }; 
} 

實現:

void Wide::Lexer::operator()() { 
    Codepoint cp; 
    Token current; 
    auto end_current_token = [&] { 
     if (current != Token()) { 
      tokens.push_back(current); 
      current = Token(); 
      cp = Codepoint(); 
     } 
    }; 
    auto check = [&](wchar_t codepoint) -> bool { 
     if (cp == codepoint) { 
      end_current_token(); 
      tokens.push_back(cp); 
      return true; 
     } 
     return true; 
    }; 
    auto is_whitespace = [&](wchar_t codepoint) { 
     return codepoint == L' ' || codepoint == L'\n' || codepoint == L'\t'; 
    }; 
    auto is_newline = [&](wchar_t codepoint) { 
     return codepoint == L'\n'; 
    }; 
    while(stream >> cp) { 
     // check for whitespace or comment first 
     if (is_whitespace(cp.cp)) { 
      end_current_token(); 
      continue; 
     } 

     if (cp == L'/') { 
      end_current_token(); 
      Codepoint backup = cp; 
      stream >> cp; // no need to check the stream for failure 
      if (cp == L'/') { 
       while(stream >> cp && !is_newline(cp.cp)); 
       continue; 
      } 
      // didn't find comment. 
      tokens.push_back(backup); 
      // put the other codepoint back 
      stream.putback(); 
      continue; 
     } 
     if (check(L'.')) continue; 
     if (check(L',')) continue; 
     if (check(L'-')) continue; 
     if (check(L';')) continue; 
     if (check(L'*')) continue; 
     if (check(L'&')) continue; 
     if (check(L'^')) continue; 
     if (check(L'%')) continue; 
     if (check(L'"')) continue; 
     if (check(L'!')) continue; 
     if (check(L':')) continue; 
     if (check(L'~')) continue; 
     if (check(L'/')) continue; 
     if (check(L'>')) continue; 
     if (check(L'<')) continue; 
     if (check(L'|')) continue; 
     if (check(L')')) continue; 
     if (check(L'(')) continue; 
     if (check(L'[')) continue; 
     if (check(L']')) continue; 
     if (check(L'}')) continue; 
     if (check(L'{')) continue; 
     // Identifier/keyword 

     current += cp; 
    } 
} 
int main() { 
    Wide::Lexer Input(L"Input.txt"); 
} 

除非管道像情侶包括,僅此而已。這是整個計劃。

+2

我不認爲你已經發布了所有相關的代碼。在這段代碼中我沒有看到任何' - >'運算符。 – Nawaz

+0

請發佈一個簡短的,**完整的**程序來展示您的問題。請參閱http://sscce.org/。 –

+0

就像我想說的那樣,這不是相關的代碼,不幸的是。編譯器錯誤指示lambda的主體。 – Puppy

回答

3

我不知道編譯器爲什麼抱怨operator->,但我想這是編譯器錯誤或Token是在別處定義的。也許該分配以某種方式被重新安排爲通過函數指針調用。

在任何情況下,我都能夠通過使用顯式命名空間範圍解析限定符來獲取代碼。試試這個:

auto end_current_token = [&] { 
     using namespace Wide; 
    if (current != Wide::Lexer::Token()) { 
     tokens.push_back(current); 
     current = Wide::Lexer::Token(); 
     cp = Wide::Lexer::Codepoint(); 
    } 
}; 

我相信 - 但我還不能肯定 - 這明確的分辨率在拉姆達的情況下總需要。

我會做更多的研究,爲什麼你有這個問題。

+0

如果這個示例未能編譯,我不會有問題。 – Puppy

+0

@DeadMG:看看我的編輯。 –

+0

有趣。我會給你一個重擊。 – Puppy