什么打破了这段代码?

时间:2013-11-25 17:02:26

标签: c++ qt compilation compiler-errors syntax-error

我很抱歉用这样一个“有意义”的标题提出一个问题,但我无法得到编译器抱怨的内容,代码工作正常,我添加了一个额外的方法,一切都破了。删除最后的更改并没有解决它。

class NodeWrapper : public QObject {
    Q_OBJECT
    Q_ENUMS(NodeType NodeStatus)
    Q_PROPERTY(NodeType type READ type WRITE setType NOTIFY typeChanged)
    Q_PROPERTY(QString typeString READ typeString NOTIFY typeChanged)
    Q_PROPERTY(NodeStatus status READ status WRITE setStatus NOTIFY statusChanged)

public:
    NodeWrapper(QObject * parent = 0) : QObject(parent) { }

    enum NodeType {
        T_NODE,
        T_FOLDER
    };

    enum NodeStatus {
        S_OK,
        S_WARNING,
        S_ERROR
    };

    // type
    inline NodeType type() { return _type; }
    inline QString typeString() { return metaObject()->enumerator(0).key(type()); }
    inline void setType(NodeType v) {
        if (_type != v) {
            _type = v;
            emit typeChanged();
        }
    }
    // status
    inline NodeStatus status() { return _node.getStatus(); }
    inline void setStatus(NodeStatus v) {
        if (_node.getStatus() != v) {
            _node.setStatus(v);
            emit statusChanged();
        }
    }

signals:
    void typeChanged();
    void statusChanged();

private:
    NodeType _type;
    Node _node;
};

错误始于S_OK枚举的NodeStatus成员:

error: expected identifier before '(' token
         S_OK,
         ^
error: expected '}' before '(' token
error: expected ')' before numeric constant
         S_OK,
         ^
error: 'NodeType' does not name a type
     inline NodeType type() { return _type; }
            ^
error: 'metaObject' was not declared in this scope
     inline QString typeString() { return metaObject()->enumerator(0).key(type()); }
                                                     ^
error: 'type' was not declared in this scope
     inline QString typeString() { return metaObject()->enumerator(0).key(type()); }
                                                                               ^
...

3 个答案:

答案 0 :(得分:7)

猜测你在这个定义之前无意中包含了<windows.h>,它通过#define将S_OK重新定义为一个数字,从而导致枚举中的编译错误。全局命名空间中的这种混乱是C兼容性的一个不幸后果,实际上最安全的选择是重命名字段(也许是S_SUCCESS?)

答案 1 :(得分:2)

S_OK被定义为HRESULT为零(winerror.h)。 尝试另一个前缀,如NS_OK或nsOK。

答案 2 :(得分:1)

如果你谷歌搜索S_OK define,你会发现在某些Windows标题中它被定义为(HRESULT)0x00000000 - 这解释了编译器抱怨parens和数字常量。

你可以做些什么来消除这个错误:

  • 不要在要使用该常量的地方包含WinAPI标头,或
  • 将其重命名为其他内容。可能会丢失S_前缀或使用其他前缀。

后者更有可能工作,因为您经常会遇到WinAPI标头。也许甚至QT都会将你的课程暴露给他们,而S_OK是一个邪恶的#define,你几乎没有机会与它对抗。