c++ - MSVC10 中的奇怪编译器错误

标签 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>
    {
        // 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
});

这会遍历标记列表,并根据代码点的内容进行判断,并从关联的枚举中为它们分配一个值。如果没有找到,则给它一个“Identifier”的值。但这无法编译。

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

这是完整错误,没有警告,也没有其他错误。什么?我该如何解决这个错误?

编辑:我做了一些重要的重构,但我在一个更简单的 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
    });
}

您能否从这段代码开始,平分显示问题的最小编辑?

关于c++ - MSVC10 中的奇怪编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8043275/

相关文章:

c++ - 没有匹配功能 - 专门的签名隐藏通用?

c++ - 从 2d std::vector 初始化 Eigen::MatrixXd

c++ - 可以使用cmake设置VC调试选项中的命令参数

visual-studio - 如何在项目上同时支持 vcxproj 和 cmake?

c++ - 等待多个线程通知的条件变量的正确方法

c++ - |= 运算符,可能的短路评估?

c++ - 在 MFC 中创建窗口时如何获得最大可能的窗口大小?

.net - 学习 MSBuild 有哪些好的初学者资源?

c++ - 引用派生类时基类的对象大小

c++ - 对于(自动 e : xxx) conflict with constructor