コピーコンストラクタと暗黙の型変換、関数オーバロードの解決、優先順位

src

#include <iostream>
using namespace std;

struct test {
	test(bool) {cout << "test(bool)" << endl;}
	test(const test&) {cout << "test(const test&)" << endl;}
	operator bool() {return true;}
};

int main() {
	cout<<"bool b=test(true)"<<endl;
	bool b=test(true);
	cout<<"test t1=test(true)"<<endl;
	test t1=test(true);
	cout<<"test t2(test(true))"<<endl;
	test t2(test(true));
}

result

bool b=test(true)
test(bool)
test t1=test(true)
test(bool)
test t2(test(true))
test(bool)

ぎゃーーーー!!!!!
何の理由があってこんなことになるのか理解不能だ。

解決しました

これ、何か神秘的なオーバーロード解決ルールがあるのかと思ったらそういうことじゃなかった。
コンストラクタに無名のインスタンスが渡された場合はコピーコンストラクタが呼ばれないということらしい。なるほどねえ。
つまりオブジェクト構築時のtest(bool)は呼ばれるがそれを代入するためのコピーコンストラクタは省略されると。
g++だと-fno-elide-constructorsでこの最適化を制御できるようだ。

まあ普通は問題ないんだけど。今回はコピーコンストラクタ内で非const参照で受けたrhsのメンバを変更するという異常なことをこころみてはまった。