У меня есть следующая простая лямбда:
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");
}
Запрет на конвейерную обработку, как у пары, вот и все.Вот и вся программа.