排他的論理和をつかったオブジェクトの交換

 x ^= y;
 y ^= x;
 x ^= y;

という感じで、二変数の値を入れ替えるのに排他的論理和を使うと一時変数を使わなくていいのですが、オブジェクトでやってみるとどうなるのかなあと思ってやってみた。

class test_obj{
    int i;
public:
    test_obj(int a) {i = a;};
    void show(){std::cout << i << "\n";}
};

int main() {
    test_obj x(0),y(1);
    x ^= y;
    y ^= x;
    x ^= y;

    x.show();
    y.show();
    
    return 0;
}

んな演算子ねえよ!! ってコンパイラに怒られました。
そりゃそーだなあ。なんかクラスの中身を無理矢理ビットとして演算するやり方はないかな。

共用体を使ってみる

というので共用体を使えば、出来るんじゃないかと思ってやってみた。

class test_obj{
    int i;
public:
    void set(int a) {i = a;};
    void show(){std::cout << i << "\n";}
};

int main() {
    union {
        test_obj x;
        unsigned char cx[sizeof(test_obj)];
    };
    union {
        test_obj y;
        unsigned char cy[sizeof(test_obj)];
    };
    x.set(1);
    y.set(0);

     for (int i = 0; i < sizeof (test_obj); i++){
        cx[i] ^= cy[i];
        cy[i] ^= cx[i];
        cx[i] ^= cy[i];
    }

     
    x.show();
    y.show();
    
    return 0;
}
1
0
[Enter キーを押すとウィンドウが閉じます]

やった! 上手くいった!
大分フールな感じだし、誰も幸せになれそうにないけど、上手くいってうれしい!

あと共用体の中で宣言するオブジェクトのクラスは、コンストラクタを持っているとコンパイルエラーが出ることがわかった。