2011-08-17 106 views
9

對於我目前正在使用的代碼,我們有時需要在一些較舊的系統上編譯使用較老的編譯器(例如,我們在舊的IBM BlueGene/L上運行模擬程序,誰的支持合同規定了一些非常古老的C++編譯器)。代碼本身使用shared_ptrs,最初編寫爲使用std :: tr1 :: shared_ptr。在舊的BlueGene機器上編譯時,我很快意識到它沒有tr1 :: implementation,所以我切換到boost :: shared_ptr。原來還有一個boost :: tr1 :: shared_ptr。現在代碼在我們的研究小組之外被廣泛使用,可移植性變得更加重要。如何處理不斷髮展的C++ std :: namespace?例如:std :: tr1 :: shared_ptr vs. std :: shared_ptr vs. boost :: shared_ptr vs. boost :: tr1 :: shared_ptr

在大型代碼庫中處理這些不斷髮展的標準庫問題的最佳實踐是什麼?我假設在新的C++ 11標準中,shared_ptr將不再位於tr1命名空間中,這增加了另一個潛力:std :: shared_ptr,但是我猜測對此的廣泛支持將是一種解決方法。我希望儘可能使用最新的標準,但需要保持可移植性。我應該堅持提升嗎?

+0

現在已經有編譯器,其中'的std :: shared_ptr'可用,如VC2010和最新版本的g ++。如果你需要支持多種不同的編譯器,堅持增強可能是最簡單的。 :) – Sven

+0

只是因爲shared_ptr將被添加到命名空間std ::並不意味着它將被*刪除*從命名空間std :: tr1 ::。我知道gcc/libstdC++會保持前進。事實上,我確信Visual Studio將是一樣的。 – emsr

+0

我想如果你環顧四周,至少在過去的兩年中,大多數編譯器都支持std :: shared_ptr。我會堅持使用std :: first,然後查找std :: tr1 ::然後嘗試按照該順序進行提升。 – emsr

回答

8

部分回答你的問題

boost::tr1正好發明了標準庫的實現沒有一個tr1。爲了從here引用文檔:

的TR1庫提供了標準庫擴展的C++技術報告 的實現。這個庫本身並不實現 的TR1組件,相反它是一個很薄的包裝器,它將包含你的 標準庫的TR1實現(如果它有一個),否則它將包含Boost庫等價物,並將它們導入 命名空間std: :tr1

+0

非常感謝您的提示 - 我不知道boost :: tr1導入到std :: tr1。現在boost :: tr1對我來說更有意義。乾杯! – MarkD

1

爲什麼不進行一些特殊的編譯時檢查?種類:

#if __GNUC__ > 3 
    #define BOOST boost:: 
#else 
    #define BOOST boost::tr1:: 
#endif 

BOOST shared_ptr<...> ... 

您可以在boost庫中查找它們,它們有很多編譯器/版本檢測代碼。

有關宏的詳細信息,請參閱this question,尤其是此鏈接:http://predef.sourceforge.net/

+0

我做類似,除了我使用std :: tr1和std ::相反。 – emsr

+0

我實際上曾經這樣做過,因爲這是最容易做的事情。當它開始變得更加糾結時(例如,一些編譯器在小版本上支持TR1的變化),我決定在庫代碼中使用'std'並讓用戶適應他的環境,他比我更瞭解它。 –

9

要檢測shared_ptr在哪個名稱空間中,您需要類似autoconf的東西 - 這就是創建autoconf(檢測平臺/編譯器變體)的原因。

AC_LANG(C++) 

AC_MSG_CHECKING([for std::shared_ptr]) 
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
    [[#include <memory>]] 
    [[std::shared_ptr<int> have_shared_ptr;]]) 
], [ 
    AC_MSG_RESULT([yes]) 
    AC_DEFINE_UNQUOTED([HAVE_STD_SHARED_PTR], 1, [Define to 1 if you have the `std::shared_ptr' class.]) 
], [ 
    AC_MSG_RESULT([no]) 
    AC_DEFINE_UNQUOTED([HAVE_STD_SHARED_PTR], 0, [Define to 1 if you have the `std::shared_ptr' class.]) 
]) 

重複了std::tr1::shared_ptrboost::tr1::shared_ptrboost::shared_ptr:你可以做到這一點。

然後,您可以創建一個shared_ptr.hpp文件是一樣的東西:

#include <config.h> 

#if defined(HAVE_STD_SHARED_PTR) 
    namespace ptr = std; 
#elif defined(HAVE_STD_TR1_SHARED_PTR) 
    namespace ptr = std::tr1; 
#elif defined(HAVE_BOOST_SHARED_PTR) 
    namespace ptr = boost; 
#elif defined(HAVE_BOOST_TR1_SHARED_PTR) 
    namespace ptr = boost::tr1; 
#else 
# error No shared_ptr found. 
#endif 

...然後你可以爲使用:

ptr::shared_ptr<int> pointer(new int(5)); 
+1

你在autoconf例子中的第二條評論應該顛倒過來 – Attila

相關問題