1

编辑:将令牌结构/枚举添加到代码块

我是 C++ 新手,所以如果我错过了一些明显的东西,请原谅我。我正在尝试编写调车场算法的 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;
        }
    }
}
4

2 回答 2

4

它给你错误,因为std::list<>::pop_front()它是一个void函数。它不返回任何东西。然而,你正在使用它,就好像它返回了一些东西一样。所以,这个问题真的是给你的:你为什么试图使用一个void函数作为一个返回值的函数?你说的Token t = tokenList.pop_front()线是什么意思?

如果您试图“弹出”列表中的第一个元素,可能的步骤顺序将包括

Token t = tokenList.front();
tokenList.pop_front();
于 2011-07-24T00:58:45.163 回答
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();

希望这可以帮助!

于 2011-07-24T01:00:42.203 回答