是什么破坏了这个代码

What breaks this code?

本文关键字:代码 坏了 是什么      更新时间:2023-10-16

很抱歉问了一个标题如此"有意义"的问题,但我不明白编译器在抱怨什么,代码刚才运行得很好,我添加了一个额外的方法,一切都坏了。删除最后的更改并没有修复它。

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;
};

错误从NodeStatus枚举的S_OK成员开始:

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()); }
                                                                               ^
...

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

S_OK被定义为HRESULT为零(winerror.h)。请尝试其他前缀,如NS_OK或nsOK。

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

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

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

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