【问题标题】:What's the difference between std::ranges::swap() and std::swap()?std::ranges::swap() 和 std::swap() 有什么区别?
【发布时间】:2021-10-01 14:33:12
【问题描述】:

在 C++20 中,有两个 swap 函数模板:std::ranges::swap(T&&, U&&)std::swap(T&, T&)

我只是想知道:

他们两个有什么区别?

【问题讨论】:

  • 由于您链接到 cppreference:这些页面中有什么不清楚的地方?

标签: c++ stl standards c++20 std-ranges


【解决方案1】:

std::swap 有问题。 std 命名空间中可能没有更高效的交换函数。如果可用,您应该启用 ADL 以查找和使用它,否则使用 std::swap。它被称为“std 2-step”:

using std::swap;
swap(a, b);

但是std::ranges::swap 没有这个问题,并且会调用 ADL 会调用的版本:

std::ranges::swap(a, b);

Here 是一个演示。

【讨论】:

  • “可能有一个更高效的交换函数不在 std 命名空间中”
  • 我们可以有把握地说:std::swap 应该完全替换为std::ranges::swap
  • @xmllmx 是的。您应该在所有新代码中使用std::ranges::swap
  • @einpoklum swap 经常为自定义类重载,这与标准库的其他大部分内容不同。如果每个人都开始使用范围版本,我们不必一直教导人们在使用 swap 之前始终记住启用 ADL。此外,范围还包括 beginend 等,这些以前也需要 ADL 才能使用自定义类型。
  • @einpoklum 问题是std::swap 经常超载,而我从未见过std::sort 超载。如果您在 Google 上搜索“std 2-step”,这是一个非常常见的习语。比如这个:what does using std::swap inside the body of a class method implementation mean?.
【解决方案2】:

粗略地说:std::ranges::swap 概括了std::swap

  • 如果TU相同,则相当于调用std::swap
  • 否则,它会将参数交换为两个范围 - 如果它们是范围。
  • 否则它将执行类似交换的过程,并在不同类型 T 和 U 之间进行移动分配。
  • 如果连这都做不到,编译将失败。

详情请参阅cppreference page

我必须说我觉得这个函数有点令人困惑和巴洛克式,但是 - 也许对范围库更有经验的人会直觉地知道它为什么有意义。

【讨论】:

  • "baroque" 本身就值得一票(尽管它在那里偷偷表达意见)。
  • @TedLyngmo:我说这是我个人的印象(“我发现”)。
  • 是的,我认为对库或语言中相对较新的新增内容提出质疑是很重要的——即使在 SO 这样的观点往往不会过时。
  • @TedLyngmo:那么,您可能会喜欢我对this question 的回答——尤其是考虑到已被接受的答案。
  • 这也是一个有趣且重要的观点。我现在觉得它不够吸引人投票,但我稍后会重新阅读。
猜你喜欢
  • 2020-09-22
  • 2017-06-18
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 2015-02-25
  • 2012-12-22
相关资源
最近更新 更多