Можно ли использовать функцию макроса в качестве тега QMetaMethod?
Qt позволяет вам иметь произвольные теги в методах slots/Q_INVOKABLE, используя этот синтаксис:
// In the class MainWindow declaration
#ifndef Q_MOC_RUN
// define the tag text as empty, so the compiler doesn't see it
# define MY_CUSTOM_TAG
#endif
...
private slots:
MY_CUSTOM_TAG void testFunc();
Я хочу сделать тег, который является функцией макроса, например:
#ifndef Q_MOC_RUN
# define MY_CUSTOM_TAG(...)
#endif
...
private slots:
MY_CUSTOM_TAG(someData) void testFunc();
Который я надеялся закончить как строку в tag()
лайк MY_CUSTOM_TAG(someData)
который мой код будет анализировать - однако MOC выдает мне эту ошибку:
error: Parse error at ")"
Есть ли способ сделать эту работу? Или MOC поддерживает только простые макросы для тегов?
1 ответ
Tl;dr - то, что вы можете сделать это, но moc придирчив к тому, что он принимает.
Согласно документу, который вы указали, moc в Qt 5.0+ расширит макросы препроцессора. Вы можете подтвердить это с помощью следующего примера:
#ifndef Q_MOC_RUN
#define MY_TAG(...)
#else
#define MY_TAG(x) x
#endif
class Test : public QObject
{
Q_OBJECT
public:
explicit Test(QObject *parent = 0);
public slots:
MY_TAG(qt) void test();
};
Если вы осмотрите МОК- сгенерированный moc_test.cpp
Вы должны найти 'qt' в сгенерированной строковой таблице.
static const qt_meta_stringdata_Test_t qt_meta_stringdata_Test = {
{
QT_MOC_LITERAL(0, 0, 4), // "Test"
QT_MOC_LITERAL(1, 5, 4), // "test"
QT_MOC_LITERAL(2, 10, 2) // "qt"
},
"Test\0test\0qt"
};
Вы также можете проверить успешность, используя QMetaMethod::tag(), как описано в связанной документации.
Я протестировал несколько других макросов и обнаружил, что moc жестко реагирует на то, что он принимает. Например, макросы с несколькими аргументами и тела макросов, включая скобки или тире, привели к ошибке. moc использует собственную реализацию препроцессора и может быть ограничена по сравнению с препроцессором GNU C.