gpt4 book ai didi

c++ - Q_ENUMS 和 using 声明不能一起工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:11:37 25 4
gpt4 key购买 nike

考虑以下类定义:

// exported.hpp

#include <QObject>

class Exported: public QObject {
Q_OBJECT

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

以及以下文件:

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

现在,QML 文件中的 Exported.BARundefined


最基本的问题是:为什么它不适用于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 };
};

这适用于 documentation Q_ENUM 实际上(强调我的):

This macro registers an enum type with the meta-object system. It must be placed after the enum declaration in a class that has the Q_OBJECT or the Q_GADGET macro.

整节未提及定义。
另一方面,我们从标准中得到了这个:

A using-declaration introduces a set of declarations into the declarative region in which the using-declaration appears.

所以,我期待它也能正常工作。不管怎样,这对我来说可能是一个错误的期望。

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

最佳答案

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

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

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 定义的范围,并且您不能转发声明 FOO.

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

关于c++ - Q_ENUMS 和 using 声明不能一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40511980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com