Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用模板、xor和指向内存的指针进行非常残酷的交换_C++_Templates_Memory_Swap_Xor - Fatal编程技术网

C++ 使用模板、xor和指向内存的指针进行非常残酷的交换

C++ 使用模板、xor和指向内存的指针进行非常残酷的交换,c++,templates,memory,swap,xor,C++,Templates,Memory,Swap,Xor,使用这种交换实现的最大威胁是什么?此外,螺纹安全性和优化效果差。什么时候失败(反例) 模板 无效swapViaMemory(T和左、T和右){ 如果(&left==&right){return;} 无符号int-tSize=sizeof(T); 无符号字符*lPtr=重新解释强制转换(&L); unsigned char*rPtr=reinterpret_cast(&right); for(无符号整数i=0;i

使用这种交换实现的最大威胁是什么?此外,螺纹安全性和优化效果差。什么时候失败(反例)

模板
无效swapViaMemory(T和左、T和右){
如果(&left==&right){return;}
无符号int-tSize=sizeof(T);
无符号字符*lPtr=重新解释强制转换(&L);
unsigned char*rPtr=reinterpret_cast(&right);
for(无符号整数i=0;i

抱歉,语法错误和拼写错误(

它无法传达意图

这是代码的主要目的

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

    swap(left, right);
}
模板
typename std::enable_if::type
SwapviamMemory(T&left,T&right)
{
使用std::swap;
交换(左、右);
}

除了令人毛骨悚然的混淆之外,如果左、右的强制转换指向同一地址,它也会失败

因为
a^a=0
(这就是您用于此“技巧”的内容)

如果
left==right
(假设它是一个包含
'a'
然后你会做:

a^a = 0
0^a = a
a^a = 0

如果T不是一个普通的可复制类型,它将调用未定义的行为。

例如:

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);
结构B{ 虚拟~B(){} }; 结构X:B { int x;
~X(){std::cout如果
T
包含一个指向其另一个成员的指针或引用的成员,则此操作将失败(假设指针/引用成员总是指向/引用属于该实例的数据成员)


如果使用
swapViaMemory
交换两个
foo
对象,例如
f1
f2
,交换后,
f1.ref_i
f1.ptr_i
将引用/指向
f2.i
,反之亦然。此外,对于引用成员,这将调用未定义的行为,因为重新定位引用是非法的nce.

怎么回事?-注意它对平等没有任何作用。对,直到你的“意图”在实践中证明不是像狗一样慢,在这种情况下,你的客户不会对你的“意图”发出两声嘘声。这里不是说这是事实,但一般来说,代码的主要目的是编译成机器语言,以便我们能够解决问题。清晰性应该一直努力,但它也应该始终放在次要位置,以便快速、出色地完成工作。@EdS。这里完全不是这样。即使是
std::copy
也会优化如果valuetype是POD,则直接进入SSE启用的
memcpy
/
memmov
。您必须进行配置。然后问题会演变为:“我可以在这里使用此黑客吗”,而不是“我什么时候不应该使用此黑客”同意,这就是我对我的评论进行限定的原因。我关心的是“[意图]是代码的主要目的”这句话,这一点我非常不同意。我还想在上面键入“结果像狗一样慢”。这对于指针成员是不正确的,除非您详细说明“这将失败”的含义。@LucDanton添加到answer@Praetorian哦,我喜欢。指针将在交换对象的成员之间交叉。
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);
struct foo
{
  foo() : i(), ref_i(i), ptr_i(&i) {}
  int i;
  int& ref_i;
  int *ptr_i;
};