Сначала прочитайте сообщения Herb's Sutters GotW о pimpl в C++11:
У меня возникли проблемы с пониманием решения, предложенного в GotW #101. Насколько я понимаю, все проблемы, кропотливо решенные в GotW #100, вернулись с удвоенной силой:
Члены
pimpl
являются шаблонами вне очереди, и определения не видны в момент использования (в определении классаclass widget
и неявно сгенерированных специальных функциях-членахwidget
). Явных экземпляров тоже нет. Это вызовет неразрешенные внешние ошибки во время компоновки.widget::impl
все еще неполный в точке, гдеpimpl<widget::impl>::~pimpl()
определяется какinstantified(я не думаю, что на самом деле он вообще создан, просто на него ссылаются). Таким образом,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 этого нет!
Херб, если вы зайдете, дайте мне знать, можно ли вырезать и вставить сюда код решения для справки.
Paging
Доктор @HerbSutter - person sehe   schedule 23.12.2011