2010-01-30 76 views
2

我使用兩個大庫(GUI &網絡),我可以愉快地做如何解決C++中兩個庫之間的命名衝突?

using namespace FirstLib; 
using namespace SecondLib; 

除1名爲Foobar地方名衝突單一類。

我是我的代碼,我不使用FirstLib::Foobar。有沒有辦法說「在我的代碼中,只要你看到Foobar,認爲SecondLib::Foobar

+4

不要使用'使用namespace'。它是爲了保護你免受你的問題而發明的,因爲它像你一樣重新引入了問題,所以它被憎惡。如果發現輸入太長,請使用命名空間別名。 – GManNickG 2010-01-30 01:00:53

+1

我不是dos和donts的粉絲。用例在學校書籍中絕不是黑色或白色。實際上,我建議的解決方案(使用使用聲明)位於http://www.parashift.com/c++-faq-lite/coding-standards.html#faq-27.5 – gaspard 2010-01-30 10:05:57

回答

2

很奇怪沒有人建議更換所使用的類名的列表完整的命名空間使用。這個解決方案甚至在C++faq(我應該首先想到)。

如果我們不能說

包括所有FirstLib,但除去SecondLib::Foobar

我們可以用精確的元素using-declarations我們需要:

using FirstLib::Boids; 
using FirstLib::Life; 
// no using FirstLib::Foobar... 
1

你必須選擇其中一個命名空間,並擺脫'使用',並顯式調用所有的類名C#有一個解決方法,但C++不afiik ...

1

你基本上回答你自己的問題。你必須明確地說出你想使用哪個類,所以你必須做SecondLib::Foobar每當你使用該類

0

您是否試過:

using SecondLib::Foobar; 

+0

它不起作用。 – gaspard 2010-01-30 09:42:19

6

using namespaceevil!命名空間分別爲,以防止出現此類問題!雖如此,但嘗試:

using namespace FirstLib; 
using namespace SecondLib; 
using SecondLib::Foobar; 

甚至(對於一些編譯器):

using namespace FirstLib; 
using namespace SecondLib; 
typedef SecondLib::Foobar Foobar; 
+3

+1但是,當惡意使用C++的任何方面時,最好解釋爲什麼可以考慮這樣的事情,否則會令人困惑。或者至少指的是C++常見問題: http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.15 – mloskot 2010-01-30 00:52:48

+0

@mloskot - 感謝您的提示 - 不錯的鏈接,我如果沒有更好的鏈接將很方便,我會把我的「邪惡」鏈接到它:P – 2010-01-30 00:55:45

+0

這兩者似乎都沒有與海灣合作委員會,也沒有在網上科莫有任何區別。 'namespace a {struct X {};} namespace b {struct X {}; }使用名稱空間a;使用命名空間b;使用b :: X;/* typedef b :: X X; */int main(){X x; }' – UncleBens 2010-01-30 01:00:36

1

我不認爲有不計名的方式。你要麼帶入整個地段,要麼單獨進行。即使你引入了全部,你也可以通過完全排除衝突的名字來消除歧義。

但是,你可以使用的typedef重命名違規類:

typedef Lib2::FooBar FooBaz; 

我猜,有衝突的功能,你可以使用一個函數指針,以「重命名」衝突之一。


我想這是一種非解決方案。我可以理解偶爾使用聲明的動機 - 有時確實會有許多不同的名稱,你會在整個地方使用 - 但是如果只有一個是衝突的:明確的。無論如何,熟悉這些庫的人會感到困惑,因爲這兩個名稱空間都被導入。

另外,使用聲明尊重範圍:您可以讓一個名稱空間在一個函數中可見,但不能在另一個名稱空間中顯示 - 假設您甚至不在該函數中使用它。

+0

'typedef Lib2 :: Foobar Foobar'不能和gcc一起工作。 – gaspard 2010-01-30 09:44:34

+0

這是Fooba * z *。 Kornel的答案是缺少具體的使用聲明應該在功能,而不是全球範圍(我認爲普通範圍規則的工作:內部範圍內的東西隱藏在外部範圍內的東西)。 – UncleBens 2010-01-30 10:34:53

+0

對不起,我的錯誤,這只是另一個答案是建議typedef沒有任何名稱更改類名顯然不起作用。 – gaspard 2010-01-30 13:55:35

0

如果加載從兩個命名空間電流範圍內的所有元素使用using namespace directove的:

using namespace FirstLib; 
using namespace SecondLib; 

和有潛力的一些名字的那些名字空間可能發生衝突,那麼你需要明確地告訴編譯器要使用,在當前範圍內的元素,通過使用using聲明:

using SecondLib::Foobar; 

由於C++標準說:

7.3.3使用聲明

1 A,使用聲明引入了一個 名稱放入 聲明性區域,該區域出現的using聲明。 該名稱是 某個實體在別處聲明的名稱的同義詞。

該行要求編譯器認爲SecondLib::Foobar,只要自己認爲Foobar在其中使用using聲明電流範圍的其餘部分。

using指令和聲明是非常有用的,但它們可能會導致與您打交道的問題。因此,儘量縮小使用任何形式的using是一個好主意。您可以在其他命名空間範圍內使用指令using namespace

namespace MyApp { 
    using namespace ::SecondLib; 
} 

甚至是一個函數。這同樣適用於using聲明。所以,這是一個好主意,縮小使用其中的任何範圍:

void foo() 
{ 
    ::SecondLib::Foobar fb; 
} 

它可能看起來乏味,但只有當你鍵入,但你最有可能使用啓用智能感知的編輯器,所以成本真的很小,但好處很大 - 沒有混淆,可讀代碼,沒有編譯問題。

這也是一個非常好的主意,不要在標頭範圍中使用using namespace。見Header files usage - Best practices - C++

我自己的建議:不要使用完整資格時,你需要使用這些類型