まず、C++11 の pimpl に関する Herb の Sutters GotW の投稿をお読みください。
GotW #101 で提案されている解決策を理解するのに苦労しています。私が理解できる限りでは、GotW #100 で苦労して解決されたすべての問題が復讐をもって戻ってきました。
メンバは標準外の
pimpl
テンプレートであり、定義は使用時に表示されません (class widget
のクラス定義および の暗黙的に生成された特別なメンバ関数widget
)。明示的なインスタンス化もありません。これにより、リンク中に未解決の外部エラーが発生します。widget::impl
インスタンス化が定義されている時点ではまだ不完全pimpl<widget::impl>::~pimpl()
です(実際にはインスタンス化されているとは思いませんが、参照されているだけです)。そのため、不完全な型へのポインターを呼び出します。自明でないデストラクタがある場合、未定義の動作が発生します。std::unique_ptr<widget::impl>::~unique_ptr()
delete
widget::impl
widget::impl
完全なコンテキストでコンパイラが特別なメンバーを生成するように強制する理由を説明してください。仕組みが見えないからです。
GotW #101 がまだ完全なwidget::~widget()
実装ファイルでの明示的な定義を必要とする場合widget::impl
は、「より堅牢な」コメント (@sehe が回答で引用したもの) について説明してください。
ラッパーが「ボイラープレートの一部を削除する」という GotW #101 の中心的な主張を見ていますが、これは (段落の残りの部分に基づいて)widget::~widget()
宣言と定義を意味しているように思えます。ですから、GotW #101 では、それはなくなっています。
ハーブさん、お立ち寄りの際は、参照用にここにソリューション コードをカット アンド ペーストしてもよろしいかどうかお知らせください。