【问题标题】:Using boost::shared_ptr with a view to replacing it later使用 boost::shared_ptr 以便稍后替换它
【发布时间】:2014-04-08 06:05:27
【问题描述】:

我正在处理需要共享指针的跨平台代码。由于我无法控制的原因,我们还不能使用 C++11。所以,我建议使用 boost::shared_ptr。当我们确实采用 C++11(可能是一年后)时,我们应该能够用 std 智能指针替换 boost 智能指针。我的问题是关于使用 boost 的最佳方式,以便以后更容易切换。模板别名不可用,因此以下内容已出:

namespace my {
    template <typename T>
    using shared_ptr = boost::shared_ptr<T>;
}

将 shared_ptr 包装在另一个结构中的另一种技术会导致 API 丑陋且不可读,因为我将不得不使用它,因此 my::shared_ptr&lt;int&gt;::type:

 namespace my  {
     template<typename T>
     struct shared_ptr
     {
          typedef boost::shared_ptr<T> type;
     };
 }

我正在寻找替代方案。任何建议将不胜感激。

编辑: 我考虑的另一个选择是:

namespace my {
     using boost::shared_ptr;
}

然后使用my::shared_ptr&lt;int&gt;。稍后我会将namespace my 中的boost 更改为std。但是,我无法决定每种方法的优缺点来做出决定。

【问题讨论】:

  • 纯文本替换可能是一个可行的选择。 boost::shared_ptr -> std::shared_ptr 不太可能在任何地方出错。
  • 我不想在后面用std替换boost :(
  • 你可以写一个三行脚本来做到这一点。
  • 请注意 boost/std 命名空间不是唯一的变化。如果使用占位符,C++11 会将它们放在 std::placeholders 命名空间中,因此 boost::_1 变为 std::placeholders::_1
  • 如果编译器不支持,它要么是 std::shared_ptr 的别名,要么是 std::tr1::shared_ptr 下的 boost 实现。

标签: c++ boost shared-ptr template-aliases


【解决方案1】:

与C++98兼容的四个选项,

1) 使用impl::shared_pointer&lt;T&gt;。并从:

namespace impl = boost;namespace impl = std;

2) (更优雅但风险更大)是在没有命名空间限定的情况下使用shared_ptr,然后从

using boost::shared_ptrusing std::shared_ptr

3)(丑,但我是首选的工业解决方案)一直使用宏。

#if DETECTC++11
#define SHARED_PTR std::shared_ptr
#else
#define SHARED_PTR boost::shared_ptr
#endif

4) 结合以上 3 个。

匿名命名空间有助于将 using 语句保持在文件的本地,因此您可以控制每个源文件,例如:

namespace{
  using std::shared_ptr;
}

(我个人一直使用 2.)。

【讨论】:

  • 感谢您的建议。 2对我来说有点冒险。我讨厌为 3 使用宏。我喜欢 1 和 4 - 我用两者的变体编辑了我的问题。
【解决方案2】:

我们在我们的项目中做了这样的事情:

#if compiler_doesnt_support_c++11
  #include <boost/shared_ptr.hpp>

  namespace std {
    using boost::shared_ptr;
  }
#elif compiler_has_c++11_in_tr1
  #include <memory>
  namespace std {
    using std::tr1::shared_ptr;
  }
#else
  #include <memory>
#endif

只需在代码中使用std::shared_ptr

是的,从技术上讲,它是未定义的行为(因为不允许您像这样将名称添加到 ::std 命名空间),但它多年来一直没有任何问题。

【讨论】:

  • 没有“技术上的 UB”,只有“UB” :-)
  • @TemplateRex 从技术上讲 ;-),你是对的。但是“UB 可能会以错误的方式结束(例如读取未初始化的值)”和“UB 很可能会正常(例如向 ::std 添加一个符号,标准库没有引用该符号)”之间存在差异。跨度>
  • 好吧,从技术上讲,编译器可以在命名空间std 中维护所有标准强制标识符的列表,并在遇到您的内容时中止编译或释放鼻恶魔。
  • @TemplateRex 当然。但我所知道的编译器都没有这样做。这就是我所指的。
  • “UB”是什么意思?
猜你喜欢
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 2013-04-29
  • 2019-04-14
  • 2011-09-13
  • 2011-09-13
相关资源
最近更新 更多