2014-09-02 54 views
0

我有一個圖書館住在自己的名字空間。每個文件都被這個命名空間包裝。當我使用標準庫時,我應該將它包含到全局命名空間還是我的庫中?此外,圖書館實習生包括什麼。他們應該進入命名空間內還是外部?我應該在我的圖書館的名字空間中#include嗎?

#include <vector> // This allows reuse 

namespace library { 
    #include <vector> // This would not leak anything 
    #include "cart.h" 
    using namespace std; 

    class Train { 
     vector<cart> carts; 
    }; 
} 

包括到全局命名空間,當用戶需要載體將使意義,也因此編譯器並不需要整合標準庫的兩個版本。另一方面,包括圖書館的名字空間確保沒有任何東西泄漏到外面。

+4

你不能做到這一點,可靠;標準庫代碼應該在'std'命名空間中,而不是'library :: std'命名空間中。如果有任何非模板化函數,系統庫將提供'std :: non_templated_function'而不是'library :: std :: non_templated_function',所以你的代碼將不會鏈接。如果一切都是模板,你可能會逃避它。 – 2014-09-02 23:22:55

+0

@JonathanLeffler這對我有意義。圖書館實習生包括什麼? – danijar 2014-09-02 23:23:37

+3

不要這樣做,包含文件將不再是自包含的。將所有'#include '語句放在文件的開頭,並在每個頭文件中正確添加'namespace'! – 2014-09-02 23:25:07

回答

2

應用'常識'表明你不能可靠地在你自己的命名空間中包含C++標準頭文件。標準庫代碼旨在位於std名稱空間中,而不是library::std名稱空間中。如果有任何非模板功能,系統庫將提供std::non_templated_function而不是library::std::non_templated_function,因此您的代碼將不會鏈接。如果所有東西都是模板,那麼您可能會逃避它,但最好不要冒險,所以不要這樣做。

另外(如由T.C.comment說明)中,C++ 11標準(ISO/IEC 14882:2011)標準明確地說,在§17.6.2.2接頭[using.headers]

¶3翻譯單元只能在任何外部聲明或定義之外包含一個標題,並且在該翻譯單元的第一個引用之前,應該在該標題中包含標題,該標題在該標題中聲明爲 的任何實體。

這當然是指來自C++標準庫的頭文件;它不會爲您自己的標題禁止這種禁止。

從理論上說,圖書館的內部接頭可以列入您的library命名空間裏,如果你想要的(但他們不應該是 - 見下文):

namespace library { 
    #include "library/internal-header.h" 
    …other declarations or definitions… 
} 

但是(如Matt McNabbcomment說明),這樣做意味着內部頭文件不能包含任何新的標準頭文件,然而內部頭文件需要使用一些(額外的)標準頭文件是非常合理的。

您可能會考慮將它們包含在您自己的內部子名稱空間中(例如,library::internal)。如果您的內部頭文件不包含自己的namespace library { … }塊,請確保始終將它們包含在包含它們的頭文件中的名稱空間library { … }括號內,但請注意,內部頭文件不再是完全獨立的。

或者,更可靠的是,您的庫的內部頭文件應該是獨立的,其內容在您的library命名空間內定義(因爲命名空間是可擴展的)。

#include "library/internal-header.h" 
namespace library { 
    …other declarations or definitions… 
} 

其中"library/internal-header.h"將包含:

namespace library { 
    namespace internal { 
     …internal declarations or definitions… 
    } 
} 

其中namespace internal {和匹配}是可選的 - 你可能需要一個using namespace library::internal;指令爲好。

兩種機制都可以工作。總的來說,儘管獨立標頭好多了(我同意πάντα ῥεῖ和他的comment和Matt McNabb)。

+0

複製和粘貼您的評論本來很好,但是您的闡述使我對這個概念更加清楚。謝謝! – danijar 2014-09-02 23:46:51

+0

值得注意的是,在命名空間中包含標準庫頭部被第17.6.2.2節[using.headers]/p3(「一個翻譯單元只包含一個只在所有外部聲明或定義之外的頭部」)明確禁止。 – 2014-09-03 00:00:55

+0

@ T.C。 - 啊,謝謝!我不像C11標準那麼熟悉C++ 11標準的空隙。 – 2014-09-03 00:04:36

相關問題