C++ MSVC10中出现奇怪的编译器错误
我有以下代码:C++ MSVC10中出现奇怪的编译器错误,c++,visual-studio-2010,c++11,C++,Visual Studio 2010,C++11,我有以下代码: 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> {
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
});
这是完全错误,没有警告,没有其他错误。什么?如何修复此错误
编辑:我做了一些重要的重构,我在一个稍微简单的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();
}
};
我已经清理并重建了这个项目
我解决了这个问题
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();
}
};
不,真的。现在它编译并运行得很好 FWIW为了在VS2010上编译,我试图编造一个最小的工作示例,并编译了以下内容,没有错误
#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
});
}
#包括
#包括
#包括
#包括
命名空间范围{命名空间Lexer{
枚举标记类型
{
开放式卷曲球拍,
闭卷背包,
名称空间,
对于
虽然
做
类型,
标识符,
};
} }
结构令牌
{
std::wstring码点;
宽::Lexer::令牌类型;
};
int main()
{
std::向量标记;
std::for_each(tokens.begin()、tokens.end()、[&](Token&t){
静态常量std::无序_映射([]()->std::无序_映射
{
//将字符串映射到令牌类型枚举值
std::无序映射结果;
//保留字
结果[L“namespace”]=Wide::Lexer::TokenType::namespace;
结果[L“for”]=Wide::Lexer::TokenType::for;
结果[L“while”]=Wide::Lexer::TokenType::while;
结果[L“do”]=Wide::Lexer::TokenType::do;
结果[L“type”]=Wide::Lexer::TokenType::type;
//标点符号
结果[L{]=Wide::Lexer::TokenType::OpenCurlyBracket;
结果[L”}“]=Wide::Lexer::TokenType::CloseCurlyBacket;
返回结果;
}());
if(mapping.find(t.Codepoints)!=mapping.end(){
t、 type=mapping.find(t.Codepoints)->second;
返回;
}
t、 type=Wide::Lexer::TokenType::Identifier;//第121行
});
}
你能从这段代码开始,将显示问题的最小编辑一分为二吗?我现在也遇到了同样的问题。我使用了其他类型,但对于您的情况,它将是这样的:
auto end_current_token = [&] {
using Wide::Lexer::TokenType; // <-- this line solves problem
if (current != Wide::Lexer::Token()) {
current.type = Wide::Lexer::TokenType::Identifier;
自动结束\u当前\u令牌=[&]{
使用Wide::Lexer::TokenType;//@NicolBolas:已注释-倒数第二行。此函数在哪个类中?Wide::Lexer::TokenType::Identifier到底是什么?@NicolBolas:它在Wide::Lexer::operator()中()
,和Wide::Lexer::TokenType
是一个枚举
,其中标识符
是一个值。需要注意的是,显式枚举限定是标准的C++11,我认为VS从2003年或2005年开始就支持它作为扩展。它肯定是在2010年。@sehe:这个项目不是最大的,但对我来说还不够小对于类型,编译器似乎并不在意——我将其更改为指向成员函数的永不过时指针,因此我怀疑它是否会在短期内将其用于任何事情。我认为将此指针置于“编译器错误”下是相当安全的。
auto end_current_token = [&] {
using Wide::Lexer::TokenType; // <-- this line solves problem
if (current != Wide::Lexer::Token()) {
current.type = Wide::Lexer::TokenType::Identifier;