4

I overloaded swap function for my class as in this answer, but while sorting (std::sort) compiler is still using std::swap. I don't see any difference between my approach and the one stated in linked answer. Here's reproduction of my code:

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

struct B
{
struct A
{
    friend void swap(A & a, A & b)
    {
        std::swap(a.a, b.a);
        std::cout << "my swap\n";   
    }

    A(int _a) : a(_a) {}
    bool operator<(const A & other) { return a < other.a; }
    int a;
};
};

int main()
{
    std::vector<B::A> v{1, 2, 3, 5, 4};
    std::sort(std::begin(v), std::end(v));
}

Also executable example provided here.

Criss
  • 581
  • 5
  • 17
  • [This](http://eel.is/c++draft/utility.requirements#swappable.requirements-3.2) might be relevant: _"It is unspecified whether a library component that has a swappable requirement includes the header to ensure an appropriate evaluation context."_ – Passer By Nov 04 '17 at 17:48
  • 1
    [Your swap function seems to be correctly called even from inside of `std` namespace.](https://wandbox.org/permlink/x6IV0XUtJaPXYPXW). Maybe it is not utilized by `std::sort`. – user7860670 Nov 04 '17 at 18:09
  • Just [pass](http://en.cppreference.com/w/cpp/algorithm/sort) a function object to std::swap and be done with it. – Vorac Nov 04 '17 at 18:12
  • @MiroslavVitkov Not sure what you mean? – Criss Nov 04 '17 at 18:44
  • 1
    Are you positive `std::swap` is being called at all? Additionally, what are you _trying_ to do?? – txtechhelp Nov 04 '17 at 18:45
  • Actually, after Jodocus's answer, I'm not sure and apparently not – Criss Nov 04 '17 at 18:46
  • @txtechhelp I'm trying to sort a vector in a way that exchanging elements (swapping) isn't exacly swapping but something slightly different – Criss Nov 04 '17 at 18:56
  • @Criss Overload the move/copy assignment/constructor – Passer By Nov 04 '17 at 20:15
  • @PasserBy Nope, unfortunatelly this doesn't do :/ What I'm actually trying to do is sort one collumn of "two-dimensional vector" (by collumn I mean i.e. `v[0][col], v[1][col], v[2][col] ...`. I don't *need* this, just for fun. Here's what currently done (including your proposition): [click](https://wandbox.org/permlink/qBOOSj5nPNzdvt0z) – Criss Nov 04 '17 at 22:44

1 Answers1

2

The standard doesn't state in its specification (§25.4.1.1 [alg.sort]) that std::sort actually is guaranteed to call swap, it only mentions that the type must fulfill certain concepts which I wouldn't interpret as a guarantee:

Requires: RandomAccessIterator shall satisfy the requirements of ValueSwappable (17.6.3.2). The type of *first shall satisfy the requirements of MoveConstructible (Table 20) and of MoveAssignable (Table 22).

It therefore rather just may call it, depending on the implementation. This answer may also provide some information on that.

Jodocus
  • 7,493
  • 1
  • 29
  • 45
  • You might want to back up your claim, a speculation isn't a great answer. The linked post is 6 years old now, and things may have changed. – Passer By Nov 04 '17 at 17:56
  • Well, proving something does not exist is a tricky thing. I cannot prove the non-existence of Russell's teapot, either. § 25.4.1.1 [alg.sort] does not state that it is using `swap`, it is only requiring `Swapable`. I wouldn't take that as a proof, but as an indication that `sort` not necessarily can get injected by a custom `swap`. – Jodocus Nov 04 '17 at 18:00
  • The ideal answer would be "the standard places no restrictions on how `std::sort` swaps things", which is proven by exhaustively going through the standard. – Passer By Nov 04 '17 at 18:03