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 吗?

    最佳答案

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

    TR1 不是规范标准。

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

    TR1 文件以以下文字开头:



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



    我已经指导过很多项目所有者如何让他们的代码使用 TR1 在 libstdc++(有 TR1)和 libc++(有 C++11)之间移植。 libc++ 将那些在 C++11 中标准化的 TR1 组件放置在 C++11 中指定的命名空间 std 中。即使在 -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 的库之间切换。

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

    10-12 22:22