3

考虑以下类定义:

// exported.hpp

#include <QObject>

class Exported: public QObject {
    Q_OBJECT

public:
    using QObject::QObject;
    enum class FOO { BAR };
    Q_ENUM(FOO)
};

以及以下main文件:

// main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>
#include "exported.hpp"

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;
    qmlRegisterType<Exported>("Package", 1, 0, "Exported");
    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    return app.exec();
}

通过这样做,我可以轻松访问 QML 中枚举的命名常量。
举个例子:

// main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import Package 1.0

ApplicationWindow {
    Rectangle {
        Component.onCompleted: {
            console.log(Exported.BAR)
        }
    }
}

只要枚举的声明包含在类中,这就会起作用。
例如,如果我如下所示更改类定义,它就不再起作用了:

// exported.hpp

#include <QObject>

enum class FOO { BAR };

class Exported: public QObject {
    Q_OBJECT

public:
    using QObject::QObject;
    using FOO = ::FOO;
    Q_ENUM(FOO)
};

现在,Exported.BAR在 QML 文件中是undefined.


最基本的问题是:为什么它不适用于using 声明
请注意,它适用于转发声明,例如:

// exported.hpp

#include <QObject>

enum class FOO { BAR };

class Exported: public QObject {
    Q_OBJECT

public:
    using QObject::QObject;
    enum class FOO;
    Q_ENUM(FOO)
    enum class FOO { BAR };
};

这对实际的文档Q_ENUM是正确的(强调我的):

该宏向元对象系统注册一个枚举类型。它必须放在具有 Q_OBJECT 或 Q_GADGET 宏的类中的枚举声明之后。

在整个部分中没有提及定义。
另一方面,我们从标准中得到了这个:

using-declaration 将一组声明引入到 using-declaration 出现的声明性区域中。

所以,我期待它也能正常工作。无论如何,这可能是我的错误期望。

也就是说,关于如何处理这种不便的任何建议?如果枚举
是在类之外定义的 ,我可以看到解决它的唯一方法是在类中定义另一个枚举并在它们之间进行一对一的映射。 它远非可维护而且确实有点乏味。

4

1 回答 1

1

这与标准 C++ 无关,至少没有直接关系。Qt 的moc在其对 C++ 语法规则的理解方面非常有限(并且有充分的理由1)。显然,这种将枚举导入类范围的方式超出了它的能力范围。

在我的代码中,当我希望 moc 为我生成 enum <-> 字符串转换时,我使用别名,但方向相反:

class Exported: public QObject {
    Q_OBJECT

public:
    using QObject::QObject;

    enum class FOO { BAR };

    Q_ENUM(FOO)
};

using FOO = Exported::Foo;

这让 moc 很高兴并且是有效的 C++。不利的一面是,您将定义拉Exported入您使用FOO' 定义的每个范围,并且您不能 forward-declare FOO

1 它是在 libclang 出现之前创建的,对于一些极端情况,一个完整的 C++ 解析器的实现成本将是非常不经济的。

于 2016-11-09T16:54:49.473 回答