Strange compiler error in MSVC10

I have the following code:

std::for_each(tokens.begin(), tokens.end(), [&](Token& t) { static const std::unordered_map<std::wstring, Wide::Lexer::TokenType> mapping([]() -> std::unordered_map<std::wstring, Wide::Lexer::TokenType> { // Maps strings to TokenType enumerated values std::unordered_map<std::wstring, Wide::Lexer::TokenType> result; // RESERVED WORD result[L"namespace"] = Wide::Lexer::TokenType::Namespace; result[L"for"] = Wide::Lexer::TokenType::For; result[L"while"] = Wide::Lexer::TokenType::While; result[L"do"] = Wide::Lexer::TokenType::Do; result[L"type"] = Wide::Lexer::TokenType::Type; // PUNCTUATION result[L"{"] = Wide::Lexer::TokenType::OpenCurlyBracket; result[L"}"] = Wide::Lexer::TokenType::CloseCurlyBacket; return result; }()); if (mapping.find(t.Codepoints) != mapping.end()) { t.type = mapping.find(t.Codepoints)->second; return; } t.type = Wide::Lexer::TokenType::Identifier; // line 121 }); 

This is repeated through the list of tokens and, judging by the contents of the code points, assigns them the value from the associated enumeration. If it is not found, specify the value "ID". But this does not compile.

 1>Lexer.cpp(121): error C2065: '__this' : undeclared identifier 1>Lexer.cpp(121): error C2227: left of '->Identifier' must point to class/struct/union/generic type 

This is a complete error, no warnings, no other errors. What kind? How can I fix this error?

Edit: I did some important refactoring, and I have the same problem in a slightly simpler lambda.

 auto end_current_token = [&] { if (current != Wide::Lexer::Token()) { current.type = Wide::Lexer::TokenType::Identifier; // error line if (reserved_words.find(current.Codepoints) != reserved_words.end()) current.type = reserved_words.find(current.Codepoints)->second; if (punctuation.find(current.Codepoints[0]) != punctuation.end()) current.type = punctuation.find(current.Codepoints[0])->second; tokens.push_back(current); current = Wide::Lexer::Token(); } }; 

I cleaned and rebuilt the project.

I fixed the problem.

 auto end_current_token = [&] { if (current != Wide::Lexer::Token()) { // WORKAROUND compiler bug- dead code struct bug_workaround_type { int Identifier; }; bug_workaround_type bug; bug_workaround_type* __this = &bug; current.type = Wide::Lexer::TokenType::Identifier; if (reserved_words.find(current.Codepoints) != reserved_words.end()) current.type = reserved_words.find(current.Codepoints)->second; if (punctuation.find(current.Codepoints[0]) != punctuation.end()) current.type = punctuation.find(current.Codepoints[0])->second; tokens.push_back(current); current = Wide::Lexer::Token(); } }; 

No really. Now it compiles and works fine.

+4
source share
2 answers

FWIW I tried to make a minimal working sample for compilation on VS2010 and compiled the following without errors.

 #include <string> #include <vector> #include <algorithm> #include <unordered_map> namespace Wide { namespace Lexer { enum TokenType { OpenCurlyBracket, CloseCurlyBacket, Namespace, For, While, Do, Type, Identifier, }; } } struct Token { std::wstring Codepoints; Wide::Lexer::TokenType type; }; int main() { std::vector<Token> tokens; std::for_each(tokens.begin(), tokens.end(), [&](Token& t) { static const std::unordered_map<std::wstring, Wide::Lexer::TokenType> mapping([]() -> std::unordered_map<std::wstring, Wide::Lexer::TokenType> { // Maps strings to TokenType enumerated values std::unordered_map<std::wstring, Wide::Lexer::TokenType> result; // RESERVED WORD result[L"namespace"] = Wide::Lexer::TokenType::Namespace; result[L"for"] = Wide::Lexer::TokenType::For; result[L"while"] = Wide::Lexer::TokenType::While; result[L"do"] = Wide::Lexer::TokenType::Do; result[L"type"] = Wide::Lexer::TokenType::Type; // PUNCTUATION result[L"{"] = Wide::Lexer::TokenType::OpenCurlyBracket; result[L"}"] = Wide::Lexer::TokenType::CloseCurlyBacket; return result; }()); if (mapping.find(t.Codepoints) != mapping.end()) { t.type = mapping.find(t.Codepoints)->second; return; } t.type = Wide::Lexer::TokenType::Identifier; // line 121 }); } 

Could you halve the minimal editing showing the problem starting with this code?

+1
source

I have the same problem. I used other types, but for your case it will be as follows:

 auto end_current_token = [&] { using Wide::Lexer::TokenType; // <-- this line solves problem if (current != Wide::Lexer::Token()) { current.type = Wide::Lexer::TokenType::Identifier; 

Now it compiles well.

+1
source

Source: https://habr.com/ru/post/1380075/


All Articles