C++11 仕様では、暗黙的に生成された特殊関数 (つまり、既定のコンストラクタ、デストラクタ、コピー/移動コンストラクタ、およびコピー/移動代入演算子) に例外仕様があることは明らかです。しかし、この仕様は、現在は推奨されていない動的例外仕様 (つまり、「throw (T1, T2, T3)」)に関してのみ記述されているようです。これは、15.4/14 の例で裏付けられています。
struct A {
A();
A(const A&) throw();
A(A&&) throw();
~A() throw(X);
};
struct B {
B() throw();
B(const B&) throw();
B(B&&) throw(Y);
~B() throw(Y);
};
struct D : public A, public B {
// Implicit declaration of D::D();
// Implicit declaration of D::D(const D&) throw();
// Implicit declaration of D::D(D&&) throw(Y);
// Implicit declaration of D::D() throw(X, Y);
};
注記は規範的ではありませんが、D のコピー コンストラクターが のthrow()
代わりに宣言されていることは注目に値しnoexcept
ます。throw()
aに違反している場合と a に違反している場合では、プログラムの動作が異なるため、違いが生じnoexcept
ます。
例の上の 15.4/14 のテキストは規範的であり、次のように述べています。
暗黙的に宣言された特別なメンバー関数 (第 12 節) には、例外仕様が必要です。f が暗黙的に宣言されたデフォルト コンストラクター、コピー コンストラクター、ムーブ コンストラクター、デストラクタ、コピー代入演算子、またはムーブ代入演算子である場合、その暗黙的な例外指定は、例外指定によって T が許可されている場合にのみ、型 ID T を指定します。 f の暗黙の定義によって直接呼び出される関数。f が直接呼び出す関数がすべての例外を許可する場合、f はすべての例外を許可し、f が直接呼び出すすべての関数が例外を許可しない場合、f は例外を許可しません。
ここでは動的な例外仕様のみが参照されていることを考えると、暗黙的に生成された特別なメンバー関数は決して宣言されないのではないかと心配していnoexcept
ます。本当にそうですか?