【问题标题】:From boost to std::experimental and furthermore c++17从 boost 到 std::experimental 以及 c++17
【发布时间】:2017-06-15 10:22:10
【问题描述】:

我通常使用 boost 来实现一些功能,特别是 boost::filesystem (1.58.0)。

我还对 string_view 使用 std::experimental(我的编译器尚未将其作为标准包含 - g++ 5.4.0 20160609)。

因为我使用的 boost 功能已经过验证,所以我想为 c++17 做好准备。

幸运的是,我在代码中使用了以下命令:

using namespace boost::filesystem; //the only exeption is to boost::filesystem::remove

using namespace std::experimental;

如果我将 boost 行替换为“using namespace std::experimental::filesystem;”,我将获得与 boost 实现完全相同的行为,而我的代码中不再进行任何更改?

在我获得具有这些功能的官方 gcc 编译器后,我需要做的就是: a) 将“std::experimental::filesystem;”更改为“std::filesystem” b) 删除'using namespace std::experimental;'行

并在我的代码中只进行更改即可获得相同的行为?

c++17 还包含哪些其他增强功能,并且可以如上所述轻松替换?

【问题讨论】:

  • 虽然一些新功能基于 Boost 库或受其启发,但 Boost 库与标准库之间可能没有一对一的转换。话虽如此,我怀疑是否会有任何重大或常见的更改(如果有的话),因此您应该能够像 Boost 文件系统库一样使用std::filesystem
  • Boost Filesystem 和 Boost Threads 是我所知道的唯一两个尝试跟踪标准提案的。这立即反映在他们在公共界面中有许多重大变化(Boost Filesystem v2/v3,而 Boost Thread 使用了十几个重要的条件编译功能选择宏)

标签: gcc boost c++17


【解决方案1】:

Boost 不是(附属于)ISO 标准。

不,您不应该盲目地期望语义相同。即使在 80%-90% 的情况下接口是兼容的,您也会得到差异。

例如boost::optional<T&> 是允许的,但在标准版本中是不允许的。还有其他区别。

一般来说,使用 using-directives 是一种不好的做法,尤其是当您使用它来记录这些差异时。如果您想让您的依赖项保持移动,最好创建自己的命名空间、包装函数。

在我的代码库中,例如我用过

namespace XXX {

     using nullopt_t = ::boost::none_t;
     static CONSTEXPR nullopt_t nullopt = {};

     template <typename T> using optional = ::boost::optional<T>;
}

我们在任何非 Boost 特定代码中独家使用此接口。

这应该有助于过渡到标准库版本,除了已经概述的语义差异。

【讨论】:

  • 我明白为什么将 using 指令与外部库(如 boost)一起使用不是一个好习惯我还读到与 std "using namespace std;" 一起使用并不好我不明白为什么。
  • 显然,这是一种选择。在标头中使用指令很少是一件好事,因为它会引起名称冲突,并且可能由于例如日常活动。 (我猜,值得注意的例外是内联命名空间和版本控制)。参见例如Why is using namespace std considered bad practice
  • 在这种情况下,我的动机是为什么它不是切换实现的可靠方法:规范不可互换。
【解决方案2】:

Boost 和后来衍生的标准化往往有所不同。

对于文件系统,有一些重大更改。在我的脑海中,一个标志变成了一个标志位域。

但是 90% 的代码是一样的。

考虑使用using namespace boost::filesystem;,而不是

#ifdef USE_BOOST_FILESYSTEM
  namespace filesystem = boost::filesystem;
#else
  namespace filesystem = std::experitmental::filesystem;
#endif

现在使用filesystem:: 作为您对 API 的使用的前缀。

在少数实现不同的地方,您可以使用更多#ifdef

该命名空间中的内容现在会在您的代码中突出显示,并且您有一个 #ifdef 来处理它们不兼容的极端情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-26
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多