我正在尝试编写一个使用外部工具的日志库
为了使库更自然,我希望能够检测使用cout的命名空间。
具体地说,结果应该像这样使用
namespace A
{
void foo()
{
cout << "Something went very wrong" << endl;
}
}
namespace B
{
void bar()
{
cout << "C should equal 3" << endl;
}
}
int main()
{
B::bar();
A::foo();
}
,结果输出应该如下所示
MODULE::B : C should equal 3
MODULE::A : Something went very wrong
我已经使用std::streambuf
将某些关键字添加到cout的输出中,我需要做的就是指定在哪个命名空间中使用哪个streambuf。
我如何实现这一目标?
我正在制作的库也将被集成到一个具有多个名称空间的项目中,这些名称空间大量使用了using namespace
声明。我需要一个不需要删除这些声明的解决方案。
edit1:我不必手动指定哪个命名空间与哪个字符串相关联或将对象添加到任何使用的命名空间(当然除了std
)
答案 0 :(得分:2)
如何创建自定义记录器流?这样,用户可以指定失败的组件,如下所示:
namespace A {
void foo()
{
log("A") << "Something went very wrong" << endl;
}
}
namespace B {
void bar()
{
log("B") << "C should equal 3" << endl;
}
}
int main()
{
B::bar();
A::foo();
}
也许自动化程度较低,但__FILE__
宏也可以提供一些信息。
答案 1 :(得分:1)
这在语言中是不可能的。如果你正在使用Clang,你可以重新编译Clang来为你执行这样的任务。
答案 2 :(得分:1)
您可能会尝试在要显示的每个命名空间中注入std::string namespace_name()
之类的函数,然后调用std::cout << namespace_name()
将导致大多数内部命名空间名称输出
答案 3 :(得分:0)
我试图实现你的目标。但它依赖于海湾合作委员会。
#include <cxxabi.h>
#include <typeinfo>
using namespace std;
string retrive_name(const char *x) {
int status;
char *realname = abi::__cxa_demangle(x, 0, 0, &status);
string n = realname;
free(realname);
return n;
}
namespace A {
struct Foo
{
static void foo() {
cout << retrive_name(typeid (Foo).name()) << endl;
}
};
}
namespace B {
struct Bar
{
static void bar() {
cout << retrive_name(typeid (Bar).name()) << endl;
}
};
}
int main() {
A::Foo::foo();
B::Bar::bar();
}
输出
A::Foo
B::Bar
这个答案显示了如何在GCC下使用abi来解码typeid(X).name()
。但是你应该使用更简单,更易读的方法。