Lingxi
Lingxi

Reputation: 14977

General swap implementation in terms of byte swap

The current implementation for general swap in the standard library is something like

template <class T>
void swap(T& a, T& b) {
  T c(move(a));
  a = move(b);
  b = move(c);
}

I'm wondering whether I can do the following instead.

template <class T>
void swap(T& a, T& b) {
  unsigned char x;
  auto pa = reintepret_cast<unsigned char*>(&a);
  auto pb = reintepret_cast<unsigned char*>(&b);
  auto pc = pa + sizeof(a);
  while (pa != pc) {
    x = *pa;
    *pa = *pb;
    *pb = x;
    ++pa, ++pb;
  }
}

I think this implementation is better in terms of space usage, as it takes only one byte.

Upvotes: 0

Views: 252

Answers (2)

Brian Rodriguez
Brian Rodriguez

Reputation: 4359

There are many considerations that need to be addressed when swapping classes. For POD types, swapping bytes works correctly. More complicated classes, however, may rely on invariants that byte-swapping won't respect. For example, consider a reference to a member variable:

struct Foo {
    Foo() : bar{}, barRef{bar} {};
    int  bar;
    int& barRef; // Expected to refer to the neighboring `bar`
};

int main()
{
    Foo f{};
    {
        Foo g{};
        byte_swap(f, g);
    }
    // `f` is now invalid: `f.barRef` is pointing to garbage
}

Upvotes: 2

JojOatXGME
JojOatXGME

Reputation: 3296

You have to consider that every class can define what should happen when an instance is copied or moved by it's own. Sometimes a class may do something different then just move it's bytes. Maybe the class stores a pointer which is pointing to a member of the same instance. Just copying the bytes would breake the instace then.


I also thing that it will not make much difference. It is not really noticeable when the application needs 60 bytes more.

Upvotes: 0

Related Questions