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

发布于 2024-12-11 12:06:06 字数 5799 浏览 0 评论 0原文

我有以下简单的 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");
}

除了像夫妇这样的管道工作,仅此而已。这就是整个计划。

I've got the following simple lambda:

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

where current is of type Token and the operator is provided. But the compiler gives a strange error:

1>Lexer.cpp(6): error C2273: 'function-style cast' : illegal as right side of '->' operator

What's the problem with this?

Edit: Much as I wish to say that this isn't all the relevant code, it is. There's not one single use of -> in the whole program, except implicitly on this, and the error message points clearly to the lambda posted. However, since it is so small, I will post all the code.

#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()();
    };
}

Implementation:

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

Barring pipework like a couple includes, that's it. That's the whole program.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

离去的眼神 2024-12-18 12:06:06

我不知道为什么编译器会抱怨 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 上下文中无论如何都需要这个显式解析。

我会做更多的研究来了解你为什么会遇到这个问题。

I do not know why the compiler is complaining about operator->, but I'm thinking it's either a compiler bug or Token is defined elsewhere. Maybe the assignment is somehow being rearranged as a call through a function pointer.

In any case, I was able to get the code to compile by using explicit namespace scope resolution qualifiers. Try this:

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

I believe -- but I'm not positive -- that this explicit resolution is needed anyway in the context of a lambda.

I'll do a little more research as to why you were having this problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文