2013-04-09 64 views
1

我想写这将使用外部工具命名空间探测

使图书馆更自然的使用日志库,我想能够检测在使用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

编译器不是已经告诉过你'A :: bar()'和'B :: foo()'有问题吗? – 2013-04-09 12:38:27

+0

可能的重复 - http://stackoverflow.com/q/10657711/2065121 – 2013-04-09 12:39:02

+0

@AndyProwl这是一个错字,感谢您注意它 – tiridactil 2013-04-09 12:43:20

回答

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__宏还可以提供一些信息。

+0

添加一个特定的记录器将做exaclty我试图实现,但有一个缺陷,我试图解决这是我需要找到并更改任何现有的cout,以防止无模块日志 – tiridactil 2013-04-09 12:49:46

+1

'#定义''' cout'到别的东西可能是唯一的选择。 – 2013-04-09 12:51:23

+1

尽管我不想''定义''cout'作为一个长期解决方案,您可以使用它来检测它的用途,并且在您为特定日志记录更改之后可以删除该定义。 – 2013-04-09 12:56:19

1

在语言这是不可能的手来指定。如果你使用的是Clang,你可以重新编译Clang来为你执行这样的任务。

1

您可以尝试注入功能像你想显示在每个命名空间std::string namespace_name(),然后调用std::cout << namespace_name()会导致最里面的命名空间名称输出

0

我试图实现你的目标。但它依赖于GCC。

#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 

这样的回答显示了如何使用ABI下GCC到还原函数typeid(X).name()。但你应该使用更简单,更可读的方法