Вы можете только Q_LOGGING_CATEGORY(cat, "awesomecategory")
один раз, потому что это по существу создает «глобальную» функцию, откуда бы она ни вызывалась (см. Ниже).Также, когда вы #include "foo.tpp"
просто помещаете содержимое этого файла в заголовок (это не «отдельная единица», как, например, исходный файл .cpp).
Если вы хотитеглобальная категория ведения журнала с именем cat
, вы можете просто создать это прямо в вашем global.h
.Я не думаю, что Q_LOGGING_CATEGORY(cat, "awesomecategory")
будет работать непосредственно в заголовке, но это легко обойти.
Вот что делают эти макросы ... на самом деле это очень просто, и гораздо яснее увидеть, что происходит:
#define Q_DECLARE_LOGGING_CATEGORY(name) \
extern const QLoggingCategory &name();
#define Q_LOGGING_CATEGORY(name, ...) \
const QLoggingCategory &name() \
{ \
static const QLoggingCategory category(__VA_ARGS__); \
return category; \
}
Так что DECLARE
- это на самом деле просто предварительное объявление экспортируемой функции.С тем же успехом можно вместо этого поместить это в global.h
(и полностью пропустить все макросы Q
):
static const QLoggingCategory &cat()
{
static const QLoggingCategory category("awesomecategory");
return category;
}
Он должен быть глобальным или, по крайней мере, в том же пространстве имен по умолчанию или толькообъявляется в одной единице, потому что ...
#define qCDebug(category, ...) \
for (bool qt_category_enabled = category().isDebugEnabled(); qt_category_enabled; qt_category_enabled = false) \
QMessageLogger(QT_MESSAGELOG_FILE, QT_MESSAGELOG_LINE, QT_MESSAGELOG_FUNC, category().categoryName()).debug(__VA_ARGS__)
Или, другими словами, созданная ранее функция cat()
вызывается в единичном (или в нашем примере, глобальном) контексте.
Конечно, если вызывать подпрограммы журналирования стиля категории только из членов одного класса, то метод cat()
может просто принадлежать этому классу.
Или сама функция cat()
может находиться в пространстве имен или даже в своем собственном классе ...
class MyLoggers
{
public:
static const QLoggingCategory &cat()
{
static const QLoggingCategory category("awesomecategory");
return category;
}
}
// used somewhere else:
qCDebug(MyLoggers::cat) << "Hello cats!";
Она гораздо более гибкая, чем те простые макросы, в которую можно поверить.
HTH
ДОБАВЛЕНО: Кажется, что приведенный ниже конкретный пример работает без ошибок.
global.h
#ifndef GLOBAL_H
#define GLOBAL_H
#include <QLoggingCategory>
static const QLoggingCategory &cat()
{
static const QLoggingCategory category("awesomecategory");
return category;
}
#endif // GLOBAL_H
foo.h
#ifndef FOO_H
#define FOO_H
#include "global.h"
template <typename T>
bool bar(T, int)
{
qCDebug(cat) << "helloworld";
return true;
}
#endif // FOO_H
baz.h
#ifndef BAZ_H
#define BAZ_H
#include "global.h"
inline void baz()
{
qCDebug(cat) << "baz() says meow.";
}
#endif // BAZ_H
main.cpp
#include "foo.h"
#include "baz.h"
int main(int argc, char *argv[])
{
bar<int>(2, 2);
baz();
return 0;
}
Отпечатки:
awesomecategory: helloworld
awesomecategory: baz() says meow.