Название: Хитрые макросы QLogCat
Отправлено: ammaximus от Ноябрь 08, 2013, 13:09
QLogCat - мой отладчик для работы через сеть. Сочетает в себе элементы QDebug и LogCat. // Макроконтур #define qlc MacroCall() #define qlcv MacroCall(QLC::Verbose) #define qlcd MacroCall(QLC::Debug) #define qlci MacroCall(QLC::Info) #define qlcw MacroCall(QLC::Warning) #define qlce MacroCall(QLC::Error) #define qlca MacroCall(QLC::Assert) #define qlcf MacroCall(QLC::Fatal)
class QLCSHARED_EXPORT QLC { public: // Уровень сообщения enum LevelType{ Verbose=0, // Временное отладочное сообщение (не должно быть фиксировано) Debug=1, // Отладка Info=2, // Информирующее сообщение Warning=3, // Предупреждение Error=4, // Ошибка Assert=5, // Утверждение Fatal=6 // Фатальная ошибка };
QLC(QString file, int line, LevelType type, QString log = QLC_DEFTAG); // Создание объекта ~QLC(); // То самое место, которое отправляет по завершению цепочки <<
QLC& operator<<(const QVariant var); };
class QLCSHARED_EXPORT MacroCall { QLC::LevelType level; public: MacroCall() :level(QLC::Debug){}
MacroCall(QLC::LevelType l) :level(l){}
QLC operator()(){ return QLC(__FILE__, __LINE__, level); } QLC operator()(QString log){ return QLC(__FILE__, __LINE__, level, log); } };
#endif // QLC_H
qlc - библиотека QLogCat. Отправка сообщений осуществляется через вызов макросов qlc или qlcX, где Х - уровень сообщения. Макросы подставляют вместо себя объект MacroCall, у которого перегружена операция (). Конструктор MacroCall получает параметр Х и запоминает его. Затем, в зависимости от набора аргументов, оператор () создает нужный QLC. Чтобы послать сообщение в QLC используется <<. Использование qlc("Logname") << "Hello";
//qlce("NotWorkLog") << "Message"; //MacroCall(QLC::Error)("NotWorkLog") << "Message";
MacroCall a(QLC::Error); a("DasCool") << "That's work!"; Итак проблема. Закомментированный код не работает, но если развернуть его на две части все ок. Что можно сделать с ()() ??? Ошибка invalid use of qualifid-name
Название: Re: Хитрые макросы QLogCat
Отправлено: Bepec от Ноябрь 08, 2013, 15:03
В первом исполняется конструктор и он не в курсах что ты там делаешь дальше с операторами. Это ж конструктор. А если разложить, то конструктор создаёт объект и вызывает у объекта оператор скобочек.
Название: Re: Хитрые макросы QLogCat
Отправлено: ammaximus от Ноябрь 08, 2013, 15:09
Мне не понятно, два конструктора, с параметром и без, в одном классе, написаны подряд. Так работает MacroCall()("NotWorkLog") << "Message"; Так нет MacroCall(QLC::Error)("NotWorkLog") << "Message";
Название: Re: Хитрые макросы QLogCat
Отправлено: ammaximus от Ноябрь 09, 2013, 12:56
Минимальный нерабочий код в студию: #include <QVariant> #include <QDebug>
class QLC { public: // Error types enum LevelType{ Debug=0, // Debug Error=1, // Error WTF = 2 // WTF??? } level;
QString logger;
// Constructors QLC(QLC::LevelType l) :level(l), logger(":") {}
QLC(QLC::LevelType l, QString log) :level(l), logger(log) {}
// OPERATOR << QLC& operator<<(const QVariant var){ qDebug() << "(" + QString::number(level) + ")" << logger << var; } };
class MacroCall { QLC::LevelType level; public: MacroCall() :level(QLC::Debug){}
MacroCall(int i) :level(QLC::WTF){}
MacroCall(QLC::LevelType l) :level(l){}
QLC operator()(){ return QLC(level); } QLC operator()(QString log){ return QLC(level, log); } };
int main(int argc, char*argv[]) { MacroCall()("WorkLog") << "No level, yes logname"; MacroCall(QLC::Error)() << "No logname, yes level";
MacroCall a(QLC::Error); a("WorkLog") << "Logname and level at different lines";
// GET READY! // INT as level and logname: MacroCall(2)("WorkLog") << "WTF?? It works!";
//MacroCall(QLC::WTF)("NotWorkLog") << "It's not work!!!!!!"; // NOT WORK: error: invalid use of qualified-name 'QLC::WTF' // Qt 4.8.3
return 0; }
Название: Re: Хитрые макросы QLogCat
Отправлено: m_ax от Ноябрь 09, 2013, 15:40
Непонятно зачем вообще MacroCall обязательно должен быть классом? Можно, например, так: C++ (Qt) template <QLC::LevelType level = QLC::Debug> QLC MacroCall(const QString & log = QString()) { return QLC(level, log); } ... MacroCall<QLC::Error>("WorkLog") << " message "; MacroCall<>("WorkLog") << " message ";
Название: Re: Хитрые макросы QLogCat
Отправлено: ammaximus от Ноябрь 10, 2013, 14:43
Искать решение за пределами проблемы :D Когда-нибудь и я так буду. Обнаружили интересный момент: http://stackoverflow.com/questions/19874867/enum-in-constructor-qt-c Проблему уже решил отказом от использования енумов: #define qlcv MacroCall(__FILE__, __LINE__, 0) #define qlcd MacroCall(__FILE__, __LINE__, 1) #define qlci MacroCall(__FILE__, __LINE__, 2) #define qlcw MacroCall(__FILE__, __LINE__, 3) #define qlce MacroCall(__FILE__, __LINE__, 4) #define qlca MacroCall(__FILE__, __LINE__, 5)
MacroCall(QString f, int l, int type) :level(QLC::LevelType(type)), file(f), line(l){}
Шаблоны круто, будет время - перепишу, для общего развития
|