6

そのようなスワップの実装を使用することの最も脅威は何ですか? スレッドの安全性と不十分な最適化に加えて。失敗するのはいつですか(反例)?

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);
    }
}

文法ミス、スペルミスでごめんなさい(=

4

5 に答える 5

5

Tが自明にコピー可能なタイプでない場合、未定義の動作を呼び出します。

于 2012-12-05T00:37:40.883 に答える
4

別のメンバーへのポインターまたは参照であるメンバーが含まれている場合T、これは失敗します (ポインター/参照メンバーが常にそのインスタンスに属するデータ メンバーを指す/参照することを意図していると仮定します)。

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

2 つのfooオブジェクト、たとえばf1&f2が を使用して交換された場合swapViaMemory、交換後にf1.ref_i/f1.ptr_iを参照しf2.i、その逆も同様です。また、参照メンバーの場合、参照を再配置することは違法であるため、未定義の動作が呼び出されます。

于 2012-12-05T00:40:37.213 に答える
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);
}
于 2012-12-05T00:35:04.300 に答える
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);
于 2012-12-05T00:39:08.927 に答える
0

left と right のキャストが同じアドレスを指している場合、ひどく難読化されるだけでなく、失敗します。

以来a^a = 0(これは、この「トリック」に使用するものです)

If left == right(そして、それが を含む 1 バイトのエンティティであると仮定し'a' ましょう。

a^a = 0
0^a = a
a^a = 0
于 2012-12-05T00:35:44.987 に答える