2013-04-09 89 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()。但你應該使用更簡單,更可讀的方法