2013-06-15 22 views
7

boostとC++ 11の両方がshared_ptrをサポートしています。コンパイラの中には、C++ 11をサポートするものもあれば、サポートしていないものもあります。コンパイラがC++ 11のshared_ptrをサポートするときに、std :: shared_ptrを使用するように自分のコードを書いてみたいと思います。そうでない場合は、boost :: shared_ptrを使用してください。そのための共通の/ベストプラクティスは何ですか?boost :: shared_ptrとstd :: shared_ptrの共存

GCCに限定して説明しますが、特定のバージョンではありません。

+1

あなたがこのような状況に陥っているなら、ブーストを*常に*使用するのはなぜですか? –

+0

http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/5213d735-58ca-452e-994f-cfc9575449a7/ – user1929959

+0

を参照してください。可能な限り、C++ 11の可用性をチェックする必要がありますhttp://stackoverflow.com/questions/1975616/determine-c0x-availabilityを参照してください。 – user1929959

答えて

3

あなただけHAS_STD_SHARED_PTRフラグはビルド環境で設定する必要があり

#ifdef HAS_STD_SHARED_PTR 
    #include <memory> 
    #define SHARED_PTR_NAMESPACE std 
#else 
    #include <boost/shared_ptr.hpp> 
    #define SHARED_PTR_NAMESPACE boost 
#endif 

namespace my_namespace { 
    using SHARED_PTR_NAMESPACE::shared_ptr; 
    using SHARED_PTR_NAMESPACE::make_shared; 
} 

#undef SHARED_PTR_NAMESPACE 

カスタム名前空間にそれらを引くことができます。 CMakedetecting such featuresの一般的な方法を可能にします。私はGCCがC++ 0xの/ C++ 11を使用しているかどうかを検出することを認識しています

+0

また、C++のバージョンをチェックすることもできます。そのためのマクロがあります: '__cplusplus' – stefan

+0

確かに1つのコンパイラに制限されます。 CMakeを使用すると、どのコンパイラツールチェーンを使用しているかにかかわらず、検出に依存することができます。 – ComicSansMS

+0

@ComicSansMS:いいえ、 'C++'のバージョンは '__cplusplus'でエンコードされています。これは標準afaik – stefan

4

C++ 0xの/ C++ 11可用性

唯一の方法は、今日のように、事前に定義されたかどうかを確認することですマクロ__GXX_EXPERIMENTAL_CXX0X__:これは将来変更される可能性があること

#ifdef __GXX_EXPERIMENTAL_CXX0X__ 
    // C++11 code 
#else 
    // C++03 code 
#endif 

注(マクロしたがってEXPERIMENTAL一部)。

編集:実際には @stephanコメントでそれを指摘するまで、私は知らなかった、より良い方法があります:

16.8/1 [cpp.predefined]

__cplusplus 

名前__cplusplusがに定義されています。次のマクロ名は、実装によって定義されなければなりません値201103L でC++翻訳単位をコンパイルした場合。

157)この規格の将来のバージョンでは、 をこのマクロの値をより大きな値に置き換えることを意図しています。不適合コンパイラ は、小数点以下5桁の値を使用する必要があります。

だから私は、あなたが行うことができると思います:

#if defined(__cplusplus) && (__cplusplus >= 201103L) 

しかし、私は、これは事前に標準C++ 0xのGCCのバージョンでは動作しません恐れています。だから私は、おそらく一緒に__GXX_EXPERIMENTAL_CXX0X____cplusplusの両方を使用したい:

#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && (__cplusplus >= 201103L)) 

C++ 0xの/ C++ 11の互換性

しかし、これは常にちょうどCかどうかを検出するのに十分ではないかもしれません++ 0x/C++ 11のサポートが有効になっています:C++ 11のサポートは、コア言語レベルだけでなくライブラリレベルでもGCCバージョン全体で大きく変化しました。

私の最善の策は、例えば、あなたがC++ 11のサポートのために許容見つけるとGCCのバージョンのテストで上記のテストを組み合わせた最小限のGCCのバージョンを確認するために、次のようになります。

boostの切り替え
#if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ >= 5)) // for GCC 4.7+ 

std

ここでboost::shared_ptrstd::shared_ptrの間で切り替えるには、C++ 03ではテンプレート化されたtypedefがサポートされていないため、少し面倒です。いずれかの私はtemplate structに必要な定義をラップします:

#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && (__cplusplus >= 201103L))) \ 
     && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ >= 5)) 
    template<typename T> 
    struct my_shared_ptr { 
     typedef std::shared_ptr<T> type; 
     // you may also want to forward make_shared etc, this is left as an exercise 
    }; 
#else 
    template<typename T> 
    struct my_shared_ptr { 
     typedef boost::shared_ptr<T> type; 
     // you may also want to forward make_shared etc, this is left as an exercise 
    }; 
#endif 

my_shared_ptr<int>::type ptr(new int); 

編集:(再び)私は単純な非テンプレートusingディレクティブで右shared_ptrをインポートするComicSansMSの道@気づいたおっと。なぜ私はそれについて考えなかったのですか?

私は、GCCでC++ 0x/C++ 11を検出する方法について説明しました。

関連する問題