1

In C++20, there are two swap function templates: std::ranges::swap(T&&, U&&) and std::swap(T&, T&).

I just wonder:

What's the difference between they two?

xmllmx
  • 39,765
  • 26
  • 162
  • 323

2 Answers2

5

std::swap has a problem. It's possible that there is a more efficient swap function that is not in the std namespace. You should enable ADL to find and use that if available and use std::swap otherwise. It's called "std 2-step":

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

But std::ranges::swap doesn't have this problem and will call the version ADL would have called:

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

Here is a demonstration.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • "It's possible that there is a more efficient swap function that is not in the std namespace" <- Isn't that theoretically true for a huge number of std namespace functions? – einpoklum Jul 25 '21 at 08:07
  • Can we safely say: `std::swap` should be totally replaced with `std::ranges::swap`? – xmllmx Jul 25 '21 at 08:07
  • 2
    @xmllmx yes. You should use `std::ranges::swap` in all new code. – Aykhan Hagverdili Jul 25 '21 at 08:08
  • 3
    @einpoklum `swap` is very often overloaded for custom classes unlike much of the rest of the standard library. If everyone starts using the ranges version, we don't have to keep teaching folks to always remember to enable ADL before using `swap` in particular. Additionally, ranges also include `begin`, `end`, etc which also previously required ADL to work with custom types at all. – Aykhan Hagverdili Jul 25 '21 at 08:14
  • @AyxanHaqverdili: 1. Teaching people to not use `std::swap()` when they want to swap is not that different then having them incant the "magic spell" of `using std::swap`. 3. If this is relevant for `std::swap`, why not `std::sort`, and all sorts of algorithms too? – einpoklum Jul 25 '21 at 08:21
  • 4
    @einpoklum The problem is that `std::swap` is very often overloaded while I've never seen `std::sort` overloaded. This is a very common idiom if you google "std 2-step". This one for instance: [what does `using std::swap` inside the body of a class method implementation mean?](https://stackoverflow.com/a/4782809/10147399). – Aykhan Hagverdili Jul 25 '21 at 08:26
-1

In rough terms: std::ranges::swap generalizes std::swap.

  • If T and U are the same, then it's equivalent to invoking std::swap.
  • Otherwise it will swap the arguments as two ranges - if they're ranges.
  • Otherwise it will perform a swap-like procedure with move assignment between the different types T and U.
  • If even that can't happen, it will fail to compile.

See the cppreference page for details.

I must say I find this function to be somewhat confusing and baroque, but then - maybe people more experienced with the range library develop an intuition as to why it makes sense.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • "_baroque_" is worth an upvote in itself (although it sneeks an opinion in there). – Ted Lyngmo Jul 25 '21 at 07:59
  • @TedLyngmo: I said it was my personal impression ("I find"). – einpoklum Jul 25 '21 at 08:01
  • Yes, and I think that it's important that relatively new additions to the library or language is questioned - even here at SO where opinions like this tend to not age well. – Ted Lyngmo Jul 25 '21 at 08:29
  • @TedLyngmo: Well, you might enjoy my answer to [this question](https://stackoverflow.com/q/39382501/1593077) then - especially in light of the accepted answer. – einpoklum Jul 25 '21 at 09:01
  • That's also an Interesting and important view. I did not find it compelling enough for an upvote right now but I will re-read it later. – Ted Lyngmo Jul 25 '21 at 09:16