- cpp20[meta cpp]
以前まで、デフォルトコンストラクタやムーブコンストラクタといった特殊メンバ関数は、odr-usedになった段階で定義される規定になっていた。しかし、sizeof
やdecltype
のオペランドのような評価されない文脈においてはodr-usedにならないため、そのような文脈では特殊メンバ関数が使用できなかった。
struct duration {
constexpr duration() {}
constexpr operator int() const { return 0; }
};
// duration d = duration(); // #1
int n = sizeof(short{duration(duration())});
上記プログラムはコンパイルエラーになる可能性がある。sizeof
のオペランドでduration
のムーブコンストラクタを実行しているが、duration
クラスがodr-usedによってインスタンス化されていないため、ムーブコンストラクタがまだ定義されていないためである。
ここで #1のコメント行を有効にすることでこのプログラムは適格となる。
このような問題を解決するため、特殊メンバ関数が定義される条件が以下のように変更になった。
「odr-used
もしくは潜在的に定数式評価される場合に特殊メンバ関数が定義される」
これによって、評価されない文脈で定数式評価した場合でも、特殊メンバ関数が利用可能となる。
この仕様は、2013年4月に欠陥報告された問題をC++20の規格書で解決したものである。問題が判明したあとコンパイラは早期に対応している可能性がある。