enum
。它们位于相同的命名空间中,但头文件不同。//C1.h
#include <QObject>
namespace SW
{
Q_NAMESPACE
enum class Enum1 {A, B};
Q_ENUM_NS(Enum1)
}
//C2.h
#include <QObject>
namespace SW
{
Q_NAMESPACE
enum class Enum2 {A, B};
Q_ENUM_NS(Enum2)
}
//main.c
#include <QDebug>
#include <QMetaEnum>
#include "C1.h"
#include "C2.h"
int main(int argc, char *argv[]) {
auto me1 = QMetaEnum::fromType<SW::Enum1>();
qDebug() << "me1 valid:" << me1.isValid();
auto me2 = QMetaEnum::fromType<SW::Enum2>();
qDebug() << "me2 valid:" << me2.isValid();
}
moc_C1.o
和 moc_C2.o
都定义了由 staticMetaObject
产生的
Q_NAMESPACE
Q_NAMESPACE
。否则 moc 会抱怨“错误:命名空间声明缺少 Q_NAMESPACE 宏。”me1 valid: true
me2 valid: true
Q_NAMESPACE
),它会编译但在运行时出现故障:me1 valid: true
me2 valid: false
问题:是否无法将
Q_NAMESPACE
用于分布在多个文件上的命名空间?
我能想到的解决这个问题的方法:
QTBUG-68611。然而,该问题因超出范围而被关闭,因为由于 Qt 元对象编译器 (moc) 的设计,对此无能为力。
简而言之,Qt 不支持多个头文件,每个头文件都有Q_NAMESPACE
宏。这是不可能的。或者,您可以
(尽管我不建议)有一个中间文件结构,如下所示:
// internal/C1.h
#include <QObject>
enum class Enum1 {A, B};
Q_ENUM_NS(Enum1)
//internal/C2.h
#include <QObject>
enum class Enum2 {A, B};
Q_ENUM_NS(Enum1)
// C.h
#include <QObject>
namespace SW
{
Q_NAMESPACE
#include internal/C1.h
#include internal/C2.h
}
或者,
Verdigris 库。它完全兼容 Qt,并且无需调用 MOC 即可启用 Qt 的功能,因此您不会收到缺少 Q_NAMESPACE 的错误。
但是您需要在某些源文件中的 W_ENUM_NS 宏和 W_NAMESPACE_IMPL 中列出所有枚举值
//foo.h
#pragma once
#include "wobjectdefs.h"
namespace lib
{
W_NAMESPACE(lib)
enum class Foo {
A,
B,
};
W_ENUM_NS(Foo, Foo::A, Foo::B)
} // namespace lib
-
// bar.h
#pragma once
#include "foo.h"
#include "wobjectdefs.h"
namespace lib
{
enum class Bar {
A,
B,
};
W_ENUM_NS(Bar, Bar::A, Bar::B)
} // namespace lib
-
#include <QCoreApplication>
#include <QDebug>
#include "bar.h"
#include "foo.h"
#include "wobjectimpl.h"
namespace lib
{
W_NAMESPACE_IMPL(lib)
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << lib::Bar::A;
qDebug() << lib::Foo::A;
return a.exec();
}
// file_1.h
namespace A {
inline namespace File1 {
Q_NAMESPACE
enum class E1{ ... };
Q_ENUM_NS(E1)
}
}
// file_2.h
namespace A {
inline namespace File2 {
Q_NAMESPACE
enum class E2{ ... };
Q_ENUM_NS(E2)
}
}