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

标签 c++ c++11 portability

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

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

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

  • 很少有关于 TR1 是在哪个版本的 Clang/MSVC/GCC 中实现的信息
  • 我无法弄清楚 -std=c++0x 开关在 Clang 中的作用,没有它也能正常编译
  • 我不确定要使用什么 namespace ,例如std::tr1::shared_ptrstd::shared_ptr

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

最佳答案

TR1 是 C++ 标准委员会所做的实验。实验的目的是为图书馆获得现场经验,希望在未来的标准中对其进行标准化。

TR1 不是规范标准。

TR1 规范指定使用命名空间std::tr1 .东西没有放入命名空间的原因 std是为了让委员会在标准化的道路上更自由地修改TR1规范。是的,当大部分 TR1 在 C++11 中标准化时,在某些地方进行了修改。

TR1 文档以这些词开头:

This technical report is non-normative. Some of the library components in this technical report may be considered for standardization in a future version of C++, but they are not currently part of any C++ standard. Some of the components in this technical report may never be standardized, and others may be standardized in a substantially changed form.

The goal of this technical report it to build more widespread existing practice for an expanded C++ standard library. It gives advice on extensions to those vendors who wish to provide them.

大多数(但不是全部)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是规范标准。

Checked just for fun, and it turns out libcxx used in Emscripten is the issue, not Clang 3.2.

我指导过许多项目所有者如何使他们使用 TR1 的代码可移植到 libstdc++(有 TR1)和 libc++(有 C++11)。 libc++ 将那些标准化为 C++11 的 TR1 组件放在命名空间 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 包含一些标准 header 是否得到定义。如果你需要无偿地包含一个 std-header 来查看是否 _LIBCPP_VERSION得到定义,使用:

#include <ciso646>  // detect std-lib

C++98/03/11 指定 <ciso646>什么都不做。所以包括在内是非常便宜的。这个头文件的 libc++ 实现除了定义 _LIBCPP_VERSION 什么都不做。 .

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

关于c++ - 当可移植性很重要时,使用 C++ 0x/TR1 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18831151/

相关文章:

c++ - <Winsock.h> 中是否有等效的 MSG_MORE?

c++ - 使用互斥锁在 C++ 中复制构造函数

C++ 绑定(bind)和 OpenCL 暗示错误 clCreateKernel : -46

c++ - C++中的语义差异,定义常量数据实例

c++ - 当我按值传递参数时对象被破坏了?

python - Django 可重用应用程序配置

c++ - C++ 中字符串和 wstring 的控制台打印

c++ - 粘贴 "::"和 "Foo"不会提供有效的预处理 token

c++ - 使用回调中的值更新 std::vector 的 GUI slider 的动态数量

c++ - 可以在 C++ 中以可移植的方式使用命名属性初始化 POD 结构吗?