Препроцессор C++ и QT MOC

Я пытаюсь что-то (возможно, глупо).

Использовали несколько макросов для создания "количества" функций в домене C++;

#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
    type name() { return m_##name; } \
    void set##name(type data) { m_##name = data; }
#include <backend/config.i>
#undef THR_CONFIG_VALUE

Основано на следующем файле config.i:

THR_CONFIG_VALUE("", "type", int, ThisType, 0)
THR_CONFIG_VALUE("", "auto", bool, AutoVar1, false)
THR_CONFIG_VALUE("", "auto", bool, AutoVar2, false)

Это прекрасно работает, я получаю ряд функций-установщиков, также генерирую переменные-члены таким же образом (для записи).

Теперь я начинаю смешиваться с вещами QT, пытаясь использовать MOC для генерации Q_PROPERTIES:

#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
    Q_PROPERTY(type name READ name WRITE set##name NOTIFY indexChanged)
#include <backend/vessel/thruster/thruster_config.i>
#undef THR_CONFIG_VALUE

МОК пофиг на такие попытки. Это спасло бы меня, набрав 170 строк Q_PROPERTY и в будущем еще несколько сотен.

Вопрос 1: почему, препроцессор и последовательность MOC? Вопрос 2: есть ли "путь QT"?

Спасибо,

3 ответа

Решение

Теперь у меня есть реализация, которая работает. Использовал вклад Вердигриса.

Немного сложно, пришлось включить C++14 и добавить это определение в файл PRO:

DEFINES += __cpp_constexpr=201304 __cpp_variable_templates=201304

Также, как я использовал пространства имен; пришлось сделать включения внутри пространства имен:

FRONTEND_BEGIN_NAMESPACE

#include <frontend/gui/helper/wobjectdefs.h>

Тогда это работает:

#define THR_CONFIG_VALUE(path, value, type, name, defaultvalue) \
    W_PROPERTY(type, name MEMBER m_##name) 
#include <backend/config.i>
#undef THR_CONFIG_VALUE

Qt имеет свой собственный способ генерирования методов получения и установки, основываясь на имени переменной, как вы это сделали.

Посмотрите на систему собственности

Я реализовал макрос для Qt, который делает то, что вы хотите, но он должен использоваться в контексте QObject или же Q_GADGET, (Q_PROPERTY нельзя использовать вне их.)

Когда я впервые написал макрос, я не понимал, что Q_PROPERTY не генерирует установщик, метод получения, метод уведомления или даже хранилище для значения. Они должны быть сгенерированы отдельно (что легко в макросе).

NOTIFY часть Q_PROPERTY требует signal быть определенным. Поскольку сигналы кодируются в C++ с помощью MOC перед вызовом препроцессора, используя #define не будет работать. (Я не использую NOTIFY в моем коде.)

Неполный пример:

#define THR_CONFIG_VALUE(type, name) \
    Q_PROPERTY(type name READ name WRITE set##name) \
    type m_##name; \
    void set##name(const type &a_value) { m_##name = a_value; } \
    ...
Другие вопросы по тегам