Очень жестокий обмен с использованием шаблона, XOR и указателей на память

Каковы наиболее угрозы использования такой реализации подкачки? Помимо безопасности потоков и плохой оптимизации. Когда это терпит неудачу (контрпример)?

template<typename T>
void swapViaMemory(T& left, T& right) {
if(&left == &right) { return ; }

unsigned int tSize = sizeof(T);
unsigned char* lPtr = reinterpret_cast<unsigned char*>(&left);
unsigned char* rPtr = reinterpret_cast<unsigned char*>(&right);

for(unsigned int i = 0; i < tSize; ++i) {
*(lPtr + i) ^= *(rPtr + i);
*(rPtr + i) ^= *(lPtr + i);
*(lPtr + i) ^= *(rPtr + i);
}
}

Извините за грамматические ошибки и орфографические ошибки (=

6

Решение

Если T содержит элемент, который является указателем или ссылкой на другой из его элементов, это потерпит неудачу (при условии, что цель состоит в том, чтобы указатель / элемент ссылки всегда указывал / ссылался на элемент данных, принадлежащий этому экземпляру).

struct foo
{
foo() : i(), ref_i(i), ptr_i(&i) {}
int i;
int& ref_i;
int *ptr_i;
};

Если два foo объекты, скажем f1 & f2 поменялись местами с помощью swapViaMemoryпосле обмена, f1.ref_i а также f1.ptr_i будет ссылаться / указывать на f2.i и наоборот. Кроме того, в случае ссылочного элемента это вызывает неопределенное поведение, поскольку повторное размещение ссылки является незаконным.

4

Другие решения

Он вызывает неопределенное поведение, если T не является тривиально копируемым типом.

5

Это не в передаче намерений.

Что является основной целью кода.

template<typename T>
typename std::enable_if<std::is_pod<T>, void>::type
swapViaMemory(T& left, T& right)
{
using std::swap;

swap(left, right);
}
4

Скажи для:

struct B{
virtual ~B() {}
};
struct X : B
{
int x;
~X() { std::cout << x; }
};
struct Y : B
{

};

//...
X x = X();
Y y;
swapViaMemory<B>(x,y);
1

Помимо того, что он ужасно запутан, он терпит неудачу, если приведенные слева и справа указывают на один и тот же адрес.

поскольку a^a = 0 (что вы используете для этого «трюка»)

Если left == right (и давайте предположим, что это 1-байтовая сущность, содержащая 'a'
Тогда вы будете делать:

a^a = 0
0^a = a
a^a = 0
0
По вопросам рекламы [email protected]