编辑:在代码块中添加了令牌结构/枚举
我是c ++的新手,所以如果我错过了一些明显的东西,请原谅我。我正在尝试编写Shunting Yard算法的c ++版本,但它不会编译,因为它给了我错误:“无法从'void'转换为'Token'(在我标记的行上)。”谁能告诉我为什么会出现这个错误?
typedef enum TokenType { None, Number, Operator, LeftParens, RightParens };
struct Token
{
enum TokenType type;
union
{
int num;
char op;
};
};
list<Token> DoShuntingYard(list<Token> tokenList)
{
stack<Token> opStack;
list<Token> output;
while (!tokenList.empty())
{
****(This Line) Token t = tokenList.pop_front();
switch (t.type)
{
case Number:
output.push_back(t);
break;
case Operator:
if (!opStack.empty())
{
Token op2 = opStack.top();
if ((IsLeftAssoc(t) && GetOpPrecedence(t) <= GetOpPrecedence(op2)) || (!IsLeftAssoc(t) && GetOpPrecedence(t) < GetOpPrecedence(op2)))
{
output.push_back(opStack.pop());
}
}
break;
}
}
}
答案 0 :(得分:4)
它为您提供错误,因为std::list<>::pop_front()
是void
函数。它没有返回任何东西。然而,你正在使用它,好像它返回一些东西。所以,问题实在是对你:为什么你试图使用void
函数作为返回值的函数?你是Token t = tokenList.pop_front()
行是什么意思?
如果您试图“弹出”列表中的第一个元素,可能的步骤顺序包括
Token t = tokenList.front();
tokenList.pop_front();
答案 1 :(得分:4)
问题是pop_front
没有返回值。如果要删除第一个元素并读取其值,可以分两步执行:
Token t = tokenList.front();
tokenList.pop_front();
该惯例在整个STL中使用,主要是出于效率原因。通过让front
返回值并pop_front
不返回任何内容,您可以根据需要捕获值,但如果您只想删除该值,则可以执行此操作,而无需删除已删除对象的不必要副本只需致电pop_front
。
稍后您将使用此代码遇到类似的错误:
output.push_back(opStack.pop());
要解决此问题,请将其拆分为两行:
output.push_back(opStack.top());
opStack.pop();
希望这有帮助!