C ++ 03缺少一些我喜欢使用的东西:std::shared_ptr
,std::function
和std::bind
。
我们无法完全切换到C ++ 11,因为项目需要使用较旧的libstdc ++版本。我知道这些东西也在Boost中,但我们不能将其用于其他原因。
因此我们开始使用C ++ 0x / TR1,我们目前使用的所有编译器版本都支持它。但是我们遇到了一些麻烦:
-std=c++0x
切换在Clang中的作用,没有它就编译好了std::tr1::shared_ptr
vs std::shared_ptr
所以,问题是:当可移植性很重要时,C ++ 0x / TR1是否可以安全使用?它是否在所有主要编译器中实现?我应该担心专有工具链等吗?我们最好坚持使用C ++ 03吗?
答案 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编译器中保持一致。