Why are std :: sort construction objects?

I created the following class to understand the behaviorstd::sort :

class X {
public:
  X(int i) : i_(i) { }
  X(X&& rhs) noexcept : i_(std::move(rhs.i_)) { mc_++; }
  X& operator=(X&& rhs) noexcept {
    i_ = std::move(rhs.i_); ao_++; return *this;
  }
  void swap(X& rhs) noexcept { std::swap(i_, rhs.i_); sw_++; } 
  friend bool operator<(const X& lhs, const X& rhs) {
    return lhs.i_ < rhs.i_;
  }
  static void reset() { mc_ = ao_ = sw_ = 0; }
private:
  int i_;
  static size_t mc_, ao_, sw_; // function-call counters
};
// void swap(X& lhs, X& rhs) { lhs.swap(rhs); }

And run the following test code:

int main() {
  std::vector<X> v;
  for (int i = 0; i < 1000000; i++) v.emplace_back(i);

  std::mt19937 g(0xa41bc9); // fixed seed to compare measurements
  std::shuffle(v.begin(), v.end(), g);

  X::reset();
  std::sort(std::begin(v), std::end(v));
}

All code in the online IDE is here: https://wandbox.org/permlink/nbwRKptakgCSHK4f .

The measured number of calls to certain functions is as follows (all with -O2or flags /O2):

   function:   move ctor    operator=        swap
  GCC 7.1.0:   5,007,335   11,700,048           0
clang 4.0.0:   4,932,061    9,973,899           0
 MSVC 19.11:   8,580,356   21,521,211           0

If I uncomment the function swap, the situation will improve:

   function:   move ctor    operator=        swap
  GCC 7.1.0:     999,999    3,685,376   4,007,336
clang 4.0.0:      72,554      254,885   4,859,507
 MSVC 19.11:     906,593    6,173,685   7,673,763

( ) . . , swap operator= , , , "" () / .

/ , ? ( std::sort) .

UPDATE

. / , :

X temp = std::move(x1);  
x1 = std::move(x2);
x2 = std::move(temp);

, , swap. : https://godbolt.org/g/ud4u9U - / , , main.

+6
1

std::sort() - . swap() ( std::partition()), , , , / . , , ( ), "" , , izject . , , , , ibject ( , , , ).

Quicker Sorting ++: .

: , , / , / , swap() . , , . , ().

+4

All Articles