对于我目前正在处理的代码,我们有时需要使用较旧的编译器编译一些较旧的系统(例如,我们在较旧的IBM BlueGene / L上运行sims,谁的支持合同规定了一些相当旧的C ++编译器)。代码本身使用shared_ptrs,最初编写使用std :: tr1 :: shared_ptr。在旧的BlueGene机器上进行编译时,我很快意识到它没有tr1 :: implementation,所以我切换到boost :: shared_ptr。结果还有一个boost :: tr1 :: shared_ptr。现在代码在我们的研究小组之外被广泛使用,可移植性变得更加重要。
在大型代码库中处理这些不断发展的标准库问题的最佳实践是什么?我假设在新的C ++ 11标准中,shared_ptr将不再位于tr1命名空间中,这增加了另一个潜力:std :: shared_ptr,但我猜这种广泛的支持将是一个方法。如果可能的话,我想使用最新的标准,但需要保持可移植性。我应该坚持使用提升吗?
答案 0 :(得分:9)
要检测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_ptr
,boost::tr1::shared_ptr
和boost::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));
答案 1 :(得分:8)
部分 回答您的问题
boost::tr1
完全是针对没有tr1
的标准库实现而发明的。引用here的文档:
TR1库提供了C ++技术报告的实现 标准库扩展。这个库本身并没有实现 TR1组件,而不是它的薄包装,将包括你的 标准库的TR1实现(如果有),否则它 将包括Boost Library的等价物,并将它们导入 namespace std :: tr1
答案 2 :(得分:1)
为什么不进行一些特殊的编译时间检查?种类:
#if __GNUC__ > 3
#define BOOST boost::
#else
#define BOOST boost::tr1::
#endif
BOOST shared_ptr<...> ...
你可以查看boost库,它们有很多编译器/版本检测代码。
有关宏的详细信息,请参阅this question,尤其是此链接:http://predef.sourceforge.net/。