私はこの記事を書き、それについていくつかのコメントをもらい、私を混乱させました。
基本的にはT2
、テンプレートパラメータとしてのみ使用されているのを見て、誤って前方宣言の機会を利用できるという結論にジャンプしました。
struct T2;
struct T1
{
std::auto_ptr<T2> obj;
};
T2
これは、同じTUのどこかを定義しなければ、UBを呼び出します。これは、その内部をstd::auto_ptr<T2>
呼び出し、完全な型に重要なデストラクタを持つ不完全な型のオブジェクトへのポインタを呼び出すことが未定義であるためです。delete
T2*
delete
[C++11: 5.3.5/5]:
削除されるオブジェクトの削除時点でのクラスタイプが不完全であり、完全なクラスに重要なデストラクタまたは割り当て解除関数がある場合、動作は定義されていません。
私がたまたま使用していたGCCツールチェーン— v4.3.3(Sourcery G ++ Lite 2009q1-203)—は親切にも、メモで知らせてくれました。
注:クラスの定義時に宣言されている場合でも、デストラクタもクラス固有の演算子deleteも呼び出されません。
ただし、他のGCCバージョンでこの診断を取得するのは難しいようです。
delete
私の不満は、不完全な型のインスタンスへのポインターがUBではなく不正な形式である場合、このようなバグを見つけるのがはるかに簡単であるということでしたが、それは実装が解決するのが難しい問題のようです。それがUBである理由を理解してください。
しかし、std::unique_ptr<T2>
代わりに使用する場合、これは安全で準拠していると言われています。
n3035は20.9.10.2で次のように述べているとされています。
のテンプレートパラメータ
T
はunique_ptr
不完全なタイプである可能性があります。
私がC++11で見つけることができるのは、次のとおりです。
[C++11: 20.7.1.1.1]:
/ 1クラステンプレート
default_delete
は、クラステンプレートのデフォルトの削除者(破棄ポリシー)として機能しますunique_ptr
。/2のテンプレートパラメータ
T
はdefault_delete
不完全なタイプである可能性があります。
ただし、default_delete
'soperator()
には完全なタイプが必要です。
[C++11: 20.7.1.1.2/4]:
T
が不完全なタイプの場合、プログラムの形式が正しくありません。
私の質問はこれだと思います:
私の記事のコメント投稿者は、次のコードのみで構成される翻訳単位は整形式で明確に定義されていると言っていますか?それとも彼らは間違っていますか?
struct T2;
struct T1
{
std::unique_ptr<T2> obj;
};
それらが正しい場合、少なくともそれstd::auto_ptr
が使用されている場合、それがUBであるという正当な理由があるとすると、コンパイラはこれをどのように実装することが期待されますか?