7

boost と c++11 の両方が shared_ptr をサポートしていることは誰もが知っています。一部のコンパイラは c++11 をサポートしていますが、サポートしていないコンパイラもあります。コンパイラが c++11 shared_ptr をサポートする場合、std::shared_ptr; を使用するようにコードを書きたいと思います。そうでない場合は、boost::shared_ptr を使用します。そのための一般的な/ベストプラクティスは何ですか?

特定のバージョンではなく、GCC に限定して説明します。

4

2 に答える 2

4

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

今日の時点で、GCC が 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

名前は、C++ 翻訳単位をコンパイルするとき__cplusplusに値に定義されます。157201103L

157) この標準の将来のバージョンでは、このマクロの値をより大きな値に置き換える予定です。非準拠のコンパイラは、最大で 5 桁の 10 進数の値を使用する必要があります。

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

#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 バージョン テストと組み合わせることです。

#if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ >= 5)) // for GCC 4.7+

boostとの切り替えstd

C++03 はテンプレート化された typedef をサポートしていないため、切り替えは少し面倒boost::shared_ptrです。std::shared_ptr私は、必要な定義を次のようにラップします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);

編集:(shared_ptr再び)おっと、単純な非テンプレートusingディレクティブで権利をインポートする@ComicSansMSの方法に気づきました。なぜ私はそれについて考えなかったのか分かりません。

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

于 2013-06-15T19:37:59.867 に答える
3

それらをカスタム名前空間にプルするだけです

#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

フラグはHAS_STD_SHARED_PTRビルド環境で設定する必要があります。CMake は、そのような機能を検出するためのいくつかのメカニズムを提供し、新しい C++ 実装は、新しい機能をすばやく簡単に検出するための機能テスト マクロも提供します。

于 2013-06-15T19:33:32.297 に答える