当可移植性很重要时,C ++ 0x / TR1是否可以安全使用?

时间:2013-09-16 14:58:07

标签: c++ c++11 portability

C ++ 03缺少一些我喜欢使用的东西:std::shared_ptrstd::functionstd::bind

我们无法完全切换到C ++ 11,因为项目需要使用较旧的libstdc ++版本。我知道这些东西也在Boost中,但我们不能将其用于其他原因。

因此我们开始使用C ++ 0x / TR1,我们目前使用的所有编译器版本都支持它。但是我们遇到了一些麻烦:

  • 关于在哪个版本的Clang / MSVC / GCC中实现TR1的信息很少
  • 我无法弄清楚-std=c++0x切换在Clang中的作用,没有它就编译好了
  • 我不确定要使用哪些命名空间,例如std::tr1::shared_ptr vs std::shared_ptr

所以,问题是:当可移植性很重要时,C ++ 0x / TR1是否可以安全使用?它是否在所有主要编译器中实现?我应该担心专有工具链等吗?我们最好坚持使用C ++ 03吗?

2 个答案:

答案 0 :(得分:7)

TR1是由C ++标准委员会制作的实验。该实验的目的是为图书馆提供现场经验,希望在未来的标准中对其进行标准化。

TR1不是规范标准。

TR1的规范指定使用名称空间std::tr1。事情没有放入命名空间std的原因是允许委员会在标准化的过程中更自由地修改TR1规范。是的,当大部分TR1在C ++ 11中被标准化时,对地方进行了修改。

TR1文件以这些词开头:

  

本技术报告不具备规范性。一些库组件   在本技术报告中可考虑标准化   C ++的未来版本,但它们目前不是任何C ++的一部分   标准。本技术报告中的某些组件可能永远不会出现   标准化,其他可以实质上标准化   改变形式。

     

这项技术报告的目标是建立更广泛存在的   练习扩展的C ++标准库。它给出了建议   那些希望提供它们的供应商的扩展。

大多数(但不是全部)TR1在2005年的gcc和MSVC时间范围内被广泛实施。 llvm libc++是在TR1时间框架之后开发的,直接针对新的C ++ 11标准,该标准将许多TR1组件移动到命名空间std,并使它们规范 (标准要求)。

已知Clang与llvm libc++和gcc的libstdc ++一起使用。

我不知道你需要在哪个std :: lib实现中移植。如果你需要移植所有的地方来实现TR1,那么它是安全的,否则就不是。但TR1不是规范标准。 C ++ 98,C ++ 03和C ++ 11是规范标准。

  

只是为了好玩而检查,结果证明在Emscripten中使用的libcxx是   这个问题,不是Clang 3.2。

我已经指导过许多项目所有者如何使用TR1在libstdc ++(包含TR1)和libc ++(包含C ++ 11)中使用TR1。 libc ++将标准化的TR1组件放在C ++ 11中指定的名称空间std中的C ++ 11中。即使在-std = c ++ 03时它也会这样做。这是作为过渡援助完成的。 libc ++不会尝试成为符合C ++ 03的库。它的生命始于C ++ 11。

libc ++有一个名为_LIBCPP_VERSION的版本号宏。如果在包含std-header之后定义了这个宏,那么你使用的是libc ++,否则就不是。所以你可以写这样的代码:

#ifdef _LIBCPP_VERSION
// using libc++

#include <memory>
typedef std::shared_ptr<MyType> MyTypePtr;

#else  // !_LIBCPP_VERSION
// not using libc++

#include <tr1/memory>
typedef std::tr1::shared_ptr<MyType> MyTypePtr;

#endif  // _LIBCPP_VERSION

请注意,您必须首先为_LIBCPP_VERSION添加一些std-header才能定义或不定义。如果您需要无偿地包含std-header以查看是否定义了_LIBCPP_VERSION,请使用:

#include <ciso646>  // detect std-lib

C ++ 98/03/11指定<ciso646>什么都不做。因此包含它非常便宜。此标头的libc ++实现除了定义_LIBCPP_VERSION之外什么都不做。

完成后,您的代码现在可以轻松地在libc ++和其他实现TR1的库之间切换。

答案 1 :(得分:1)

我没有尝试让TR1适用于所有不同的编译器,而是只使用提升代码(仅限标题)并将其复制粘贴到您自己的项目中(因为无论出于何种原因您都无法直接使用boost) 。 boost版本得到了很好的支持和调试,并且可以在boost支持的任何C ++ 98编译器中保持一致。