Reputation: 14977
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
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
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