Сначала прочитайте сообщения Херта Саттерса GotW, касающиеся pimpl в C ++ 11:
У меня возникли проблемыпонимание решения, предложенного в 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, это ушло!
Трава, если вы заходите, пожалуйста, дайте мне знать, если это будет хорошо, чтобы вырезать + вставитьКод решения здесь для справки.