LINUX.ORG.RU

объединить два макроса

 ,


0

3

Пусть есть два макроса для лога:

#define LOG1(mess, args...) LOG_BASE(mess, ## args)
#define LOG2(mess, args...) LOG_BASE(metaObject()->className(), mess, ## args)

Тогда LOG2 использую только внутри метода класса-наследника QObject, а иначе LOG1

Как бы «просто» объединить их для удобства в LOG, чтобы по контексту определялось и использовалось или LOG2 или LOG1 ?

★★★★★
Ответ на: комментарий от ox55ff

гуглил, но уж очень сложно выглядит ) думал есть решение проще

x905 ★★★★★
() автор топика
Ответ на: комментарий от x905

В общих чертах идея состоит в том, чтобы везде использовать второй вариант макроса. Подозреваю, что в Qt есть только metaObject(), поэтому вне Qt-классов компилятор не сможет найти metaObject(). Если же определить функцию глобально, компилятор будет внутри Qt-классов делать вызов метода, а вне Qt-классов — этой самой глобальной функции. Осталось только определить функцию так, чтобы она возвращала указатель на класс или структуру, в которой есть метод className(), который будет возвращать, скажем, пустую строку.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

хм, да, попробую … а metaObject()->className() могу заменить на типа log_module_name() внутри класса

x905 ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

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

Зачем столько телодвижений?

void metaObject(); // заглушка без определения
#define LOG \
	if (requires {{metaObject()}->std::same_as<void>;})\
		// without metaObject
	else\
		// with metaObject
kvpfs ★★
()
Ответ на: комментарий от kvpfs

Зачем столько телодвижений?

Упёрся в стену, зачем-то сильно урезали в правах generic лямбды. Идея была «отключении» ветки if’а через проверку зависимого типа f, но никак не выходит, валидность else ветки проверяется даже тогда, когда вырожение == true. Может я чего-то сам напутал, но пока печально, жаль, что не работает.

#include <type_traits>
#include <iostream>
using namespace std;

namespace details {
    void metaObject();
}

#define LOG \
    { \
        using namespace ::details; \
        using is_notmember_t = \
            bool_constant<requires {{metaObject()}->std::same_as<void>;}>; \
        [&](auto f) { \
            if constexpr (same_as<decltype(f), bool_constant<true>>) { \
                cout << "not member\n"; \
            } \
            else { \
                metaObject().call(); \
            } \
        }(is_notmember_t{}); \
    }


struct Q {void call() {cout << "member\n";}};
struct Test {
    Q metaObject() {return Q{};}
    void fn() {
        LOG;
    }
};

int main() {
    Test t;
    t.fn();
    LOG;
}
kvpfs ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.