【问题标题】:How to handle evolving c++ std:: namespace? e.g.: std::tr1::shared_ptr vs. std::shared_ptr vs. boost::shared_ptr vs. boost::tr1::shared_ptr如何处理不断发展的 c++ std:: 命名空间?例如:std::tr1::shared_ptr vs. std::shared_ptr vs. boost::shared_ptr vs. boost::tr1::shared_ptr
【发布时间】:2011-10-29 01:29:03
【问题描述】:

对于我目前正在处理的代码,我们有时需要在一些较旧的系统上使用较旧的编译器进行编译(例如,我们在较旧的 IBM BlueGene/L 上运行 sims,其支持合同规定了一些相当旧的 C++ 编译器)。代码本身使用了 shared_ptr,最初是为了使用 std::tr1::shared_ptr 而编写的。在旧的 BlueGene 机器上编译时,我很快意识到它没有 tr1:: 实现,所以我切换到 boost::shared_ptr。原来还有一个 boost::tr1::shared_ptr。现在代码在我们的研究小组之外被更广泛地使用,可移植性变得更加重要。

在大型代码库中处理这些不断演变的标准库问题的(?)最佳实践是什么?我假设在新的 C++11 标准中,shared_ptr 将不再位于 tr1 命名空间中,这增加了另一个潜力:std::shared_ptr,但是我猜想对此的广泛支持将是一段路要走。如果可能的话,我想使用最新的标准,但需要保持可移植性。我应该坚持使用 boost 吗?

【问题讨论】:

  • 已经有可以使用std::shared_ptr 的编译器,例如VC2010 和最新版本的g++。如果您需要支持多种不同的编译器,那么坚持使用 boost 可能是最简单的。 :)
  • shared_ptr 将被添加到命名空间 std:: 中并不意味着它将从命名空间 std::tr1:: 中删除。我知道 gcc/libstdc++ 将保持两者向前发展。事实上,我相信 Visual Studio 也会如此。
  • 我认为,如果您环顾四周,至少在过去两年中,大多数编译器对 std::shared_ptr 的支持非常广泛。我会先坚持使用 std::,然后寻找 std::tr1:: 然后按该顺序尝试 boost。

标签: c++ boost portability std tr1


【解决方案1】:

要检测 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));

【讨论】:

  • 您在 autoconf 示例中的第二条评论应该倒置
【解决方案2】:

部分回答您的问题

boost::tr1 是专为没有tr1 的标准库实现而发明的。引用here的文档:

TR1 库提供了 C++ 技术报告的实现 关于标准库扩展。这个库本身并没有实现 TR1 组件,而是一个薄包装器,其中包含您的 标准库的 TR1 实现(如果有),否则 将包含 Boost Library 等价物,并将它们导入 命名空间 std::tr1

【讨论】:

  • 非常感谢您的提示-我不知道 boost::tr1 导入了 std::tr1。现在拥有 boost::tr1 对我来说更有意义。干杯!
【解决方案3】:

为什么不进行一些特殊的编译时检查?种类:

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

BOOST shared_ptr<...> ...

你可以在 boost 库中查找,它们有很多编译器/版本检测代码。

有关宏的详细信息,请参阅this question,尤其是此链接:http://predef.sourceforge.net/

【讨论】:

  • 我做的类似,只是我使用 std::tr1 和 std:: 代替。
  • 我实际上曾经做过类似的事情,因为这是最简单的事情。当它开始变得更加纠结时(例如,一些编译器在 TR1 支持中的小版本发生了变化)我决定只在库代码中使用 std 并让用户适应他的环境,他比我更了解。跨度>
猜你喜欢
  • 1970-01-01
  • 2012-03-10
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 2011-04-19
  • 2012-06-11
  • 1970-01-01
相关资源
最近更新 更多