gpt4 book ai didi

带有模板访问器的 Qt Q_PROPERTY

转载 作者:行者123 更新时间:2023-12-04 03:05:00 24 4
gpt4 key购买 nike

我的目标是实现更多的代码重用,同时保持冗长。

考虑以下示例代码:

// qdot@defixio /tmp/test4 $ cat test.h
#include <QObject>

class Foo : public QObject {
Q_OBJECT
// Q_PROPERTY(int bar1 READ bar<1>)
// Q_PROPERTY(int bar2 READ bar<2>)

public:
template <int i> int bar() const;
};

// qdot@defixio /tmp/test4 $ cat test.cpp
#include "test.h"
#include <QDebug>


template <int i>
int Foo::bar() const { qDebug() << "Template parameter" << i; }

int main() {
Foo foo;
foo.bar<1>();
foo.bar<2>();
return 0;
}

这个编译并按预期运行。

如果你想知道为什么我会喜欢 - 想象一组属性,DESIGNABLE 等,但属于同一个“类” - 在这种情况下,我想有单独的属性,使用 enum-templatetyped访问器。

取消注释属性定义,会导致以下 moc 错误:

/usr/bin/moc -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. test.h -o moc_test.cpp
test.h:5: Parse error at "bar"

关于如何正确混合模板和 moc 的任何想法?


回答 cmannet85 的评论,并添加更多见解 - 是的,moc 调用从 moc.h 生成 moc_test.cpp

为了进一步测试和演示它,我添加了另一个属性

Q_PROPERTY(int baz1 READ baz1)

moc_test.cpp前后的区别是:

--- moc_test.cpp        2012-10-02 13:23:39.442333849 +0200
+++ moc_test_baz1.cpp 2012-10-02 13:23:29.822328462 +0200
@@ -1,7 +1,7 @@
/****************************************************************************
** Meta object code from reading C++ file 'test.h'
**
-** Created: Tue Oct 2 13:23:39 2012
+** Created: Tue Oct 2 13:22:27 2012
** by: The Qt Meta Object Compiler version 63 (Qt 4.8.3)
**
** WARNING! All changes made in this file will be lost!
@@ -24,17 +24,20 @@
0, // classname
0, 0, // classinfo
0, 0, // methods
- 0, 0, // properties
+ 1, 14, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount

+ // properties: name, type, flags
+ 8, 4, 0x02095001,
+
0 // eod
};

static const char qt_meta_stringdata_Foo[] = {
- "Foo\0"
+ "Foo\0int\0baz1\0"
};

void Foo::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
@@ -76,6 +79,30 @@
_id = QObject::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
+
+#ifndef QT_NO_PROPERTIES
+ if (_c == QMetaObject::ReadProperty) {
+ void *_v = _a[0];
+ switch (_id) {
+ case 0: *reinterpret_cast< int*>(_v) = baz1(); break;
+ }
+ _id -= 1;
+ } else if (_c == QMetaObject::WriteProperty) {
+ _id -= 1;
+ } else if (_c == QMetaObject::ResetProperty) {
+ _id -= 1;
+ } else if (_c == QMetaObject::QueryPropertyDesignable) {
+ _id -= 1;
+ } else if (_c == QMetaObject::QueryPropertyScriptable) {
+ _id -= 1;
+ } else if (_c == QMetaObject::QueryPropertyStored) {
+ _id -= 1;
+ } else if (_c == QMetaObject::QueryPropertyEditable) {
+ _id -= 1;
+ } else if (_c == QMetaObject::QueryPropertyUser) {
+ _id -= 1;
+ }
+#endif // QT_NO_PROPERTIES
return _id;
}
QT_END_MOC_NAMESPACE

绝对没有什么可以阻止 moc 将整个 bar<1> 语句复制到 QMetaObject::ReadProperty switch 语句中——但它以某种方式在 <> 模板标签上 barfs。

最佳答案

moc 不喜欢 Q_PROPERTY 声明中的模板大括号。您可以执行以下操作:

class Foo : public QObject {
Q_OBJECT
Q_PROPERTY(int bar1 READ bar_1)
Q_PROPERTY(int bar2 READ bar_2)

private:
inline int bar_1() const { return bar<1>(); }
inline int bar_2() const { return bar<2>(); }

public:
template <int i> int bar() const;
};

moc 生成的代码应该能够访问您的类的私有(private)方法,并且这种间接访问不应导致任何运行时成本,因为编译器可以内联对 bar_N 的调用>.

您可能想在宏中隐藏 bar_N 的声明。

关于带有模板访问器的 Qt Q_PROPERTY,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12689162/

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