无法与默认构造的rvalue进行比较

时间:2011-10-22 16:41:54

标签: c++ visual-studio-2010

我有以下简单的lambda:

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

其中current的类型为Token,并提供了运算符。但编译器给出了一个奇怪的错误:

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");
}

禁止管道工作就像一对夫妇包括,就是这样。这就是整个计划。

1 个答案:

答案 0 :(得分: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();
    }
};

我相信 - 但我不是肯定的 - 无论如何在lambda的背景下都需要这个明确的解决方案。

我会就你遇到这个问题的原因做一些研究。

相关问题