4

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

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

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

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

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

4

2 回答 2

7

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

TR1 不是规范标准。

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

TR1 文件以这些词开头:

本技术报告是非规范性的。本技术报告中的一些库组件可能会考虑在未来的 C++ 版本中进行标准化,但它们目前不是任何 C++ 标准的一部分。本技术报告中的某些组件可能永远不会标准化,而其他组件可能会以重大变化的形式标准化。

本技术报告的目标是为扩展的 C++ 标准库构建更广泛的现有实践。它为希望提供这些服务的供应商提供有关扩展的建议。

大多数(但不是全部)TR1 在 2005 年跨 gcc 和 MSVC 的时间范围内被广泛实施。llvm libc++是在 TR1 时间框架之后开发的,直接针对新的 C++11 标准,该标准将许多 TR1 组件移动到 namespace 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)之间可移植。libc++ 将那些标准化为 C++11 的 TR1 组件放置在 C++11 中std指定的命名空间中。即使 -std=c++03 也是如此。这是作为过渡辅助完成的。libc++ 不会尝试成为符合 C++03 的库。它的生命始于 C++11。

libc++ 有一个版本号宏,称为_LIBCPP_VERSION. 如果这个宏是在包含一个标准头之后定义的,那么你正在使用 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

请注意,您必须首先包含一些 std-header_LIBCPP_VERSION才能定义或不定义。如果您需要免费包含一个 std-header 以查看是否已_LIBCPP_VERSION定义,请使用:

#include <ciso646>  // detect std-lib

C++98/03/11 指定<ciso646>绝对不做任何事情。所以包含它是非常便宜的。这个头文件的 libc++ 实现除了定义_LIBCPP_VERSION.

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

于 2013-09-16T15:56:44.687 回答
0

与其试图让 TR1 在你所有不同的编译器上工作,我只会使用 boost 代码(仅标题)并将其复制粘贴到你自己的项目中(因为无论出于何种原因你都不能直接使用 boost)。boost 版本得到了很好的支持和调试,并且可以在 boost 支持的任何 C++98 编译器中一致地工作。

于 2013-09-16T15:31:51.817 回答