使用模板,xor和指向内存的非常残酷的交换

时间:2012-12-05 00:32:47

标签: c++ templates memory swap 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);
    }
}

对不起语法错误和拼写错误(=

5 个答案:

答案 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_if1.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