我希望您能在保持冗长的同时,提高代码重用性。以下是示例代码:
这个程序按预期进行编译和运行。
如果你想知道为什么我想要这样做 - 想象一组属性,如DESIGNABLE等,但归属于同一个“类” - 在这种情况下,我希望使用枚举模板类型的访问器来获得单独的属性。
取消注释属性定义会导致以下 moc 错误:
有没有什么好的方法来正确地混合使用模板和moc?
为了回答cmannet85的评论并增加更多见解 - 是的,这个moc调用从moc.h生成moc_test.cpp。
为了进一步测试和演示它,我添加了另一个属性。
// 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等,但归属于同一个“类” - 在这种情况下,我希望使用枚举模板类型的访问器来获得单独的属性。
取消注释属性定义会导致以下 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 语句中,但某种方式它在 <> 模板标签方面出现问题。
moc
在 C++ 预处理器之前运行(用 'real' C++ 替换所有 Qt 关键字),因此模板代码不会被展开 -moc
本身也无法做到这一点。 这就是解析错误所指的。 - cmannett85moc
使用自己的解析器,只能识别 C++ 的一个子集。 - Stefan Majewsky