Невозможно сравнить с созданным по умолчанию значением rvalue - PullRequest
1 голос
/ 22 октября 2011

У меня есть следующая простая лямбда:

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, и сообщение об ошибке ясно указывает на опубликованную лямбду.Однако, поскольку он настолько мал, я выложу весь код.

#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 Ответ

3 голосов
/ 22 октября 2011

Я не знаю, почему компилятор жалуется на 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();
    }
};

Я верю, но я не уверен, что это явное разрешение необходимо в любом случае в контексте лямбды.

Я проведу немного больше исследований, чтобы выяснить, почему у вас возникла эта проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...