
項目 26:ユニヴァーサル参照をとるオーバロードは避ける
|
185
// this won't compile!
p から新規 Person を作成。コン
パイルできない!
上例ではある Person から別の Person を作成しようとしており、コピーコンストラクトが実行
される分かりやすい例のようにも見えます(p は左辺値のため、ムーブ演算経由で「コピー」が実
行される可能性について一切考慮する必要がない)。しかし、上例はコピーコンストラクタを呼び
出さず、完全転送コンストラクタを呼び出します。そして Person のメンバ変数 std::string を
Person オブジェクトで初期化しようとします(p)。std::string は Person をとるコンストラク
タなど実装していないため、コンパイラは憤然して何もできず、お手上げとなります。恐らくは、
ご機嫌を損ねた罰として長大かつ難解なエラーメッセージを投げつけて来るでしょう。
「なぜ?」と反論したくなるかもしれません。「なぜ、コピーコンストラクタじゃなくて完全転送
コンストラクタが呼び出されるんだ? Person を Person で初期化しているんだぞ!」えぇ、まった
くその通りです。しかしコンパイラは C++ の規則に忠実であることを誓っており、ここで適用され
るのは関数を呼び出す際のオーバロード解決に関する規則です。
コンパイラの言い分は次のようなものです。cloneOfP に与えられている初期化子は非 const な
左辺値であるた ...