使用此类交换实施的最大威胁是什么?除了线程安全和差的优化。什么时候失败(反例)?
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);
}
}
对不起语法错误和拼写错误(=
答案 0 :(得分:5)
如果T不是一个简单的可复制类型,它会调用未定义的行为。
答案 1 :(得分:4)
未能传达意图。
代码的主要目的是什么。
template<typename T>
typename std::enable_if<std::is_pod<T>, void>::type
swapViaMemory(T& left, T& right)
{
using std::swap;
swap(left, right);
}
答案 2 :(得分:4)
如果T
包含一个成员,该成员是指向另一个成员的指针或引用,则这将失败(假设意图是指针/引用成员始终指向/引用属于该实例的数据成员)。
struct foo
{
foo() : i(), ref_i(i), ptr_i(&i) {}
int i;
int& ref_i;
int *ptr_i;
};
如果有两个foo
个对象,请说f1
&amp;使用f2
交换swapViaMemory
,交换后,f1.ref_i
和f1.ptr_i
将引用/指向f2.i
,反之亦然。此外,如果是引用成员,则会调用未定义的行为,因为重新定位引用是非法的。
答案 3 :(得分:1)
说:
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);
答案 4 :(得分:0)
除了可怕的混淆之外,如果左右投射指向相同的地址,它将失败。
从a^a = 0
开始(这就是你用来'诀窍'的那个)
如果left == right
(并假设它是一个包含'a'
的1字节实体
然后你会做:
a^a = 0
0^a = a
a^a = 0