boost :: shared_ptr和std :: shared_ptr共存

时间:2013-06-15 19:21:42

标签: c++ boost c++11 shared-ptr

我们都知道boost和c ++ 11都支持shared_ptr。有些编译器支持c ++ 11,而有些编译器则不支持。我想编写我的代码,以便当编译器支持c ++ 11 shared_ptr时,它使用std :: shared_ptr;如果没有,请使用boost :: shared_ptr。最常见/最佳做法是什么?

让我将讨论局限于GCC,而不是特定版本。

2 个答案:

答案 0 :(得分: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
     

名称__cplusplus定义为值201103L时   编译C ++翻译单元。 157

     

157)本标准的未来版本将取代   具有更大值的此宏的值。不合格的编译器   应使用最多五位小数的值。

所以我想你可以做到:

#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+

booststd

之间切换

现在,要在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);

编辑:(再次)哎呀我刚注意到@ ComicSansMS使用简单的非模板shared_ptr指令导入右using的方法。不知道为什么我没有想到这一点。

尽管如此,我仍然坚持我在GCC上检测C ++ 0x / C ++ 11的方式。

答案 1 :(得分: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允许detecting such features的通用方式。