无法与默认构造的右值进行比较
我有以下简单的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不知道为什么编译器会抱怨
operator->
,但我认为这要么是编译器错误,要么是Token
在其他地方定义。也许该赋值以某种方式被重新排列为通过函数指针的调用。无论如何,我都能够通过使用显式命名空间范围解析限定符来编译代码。试试这个:
我相信——但我并不肯定——在 lambda 上下文中无论如何都需要这个显式解析。
我会做更多的研究来了解你为什么会遇到这个问题。
I do not know why the compiler is complaining about
operator->
, but I'm thinking it's either a compiler bug orToken
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:
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.