Решает ли "решение" GotW #101 что-нибудь на самом деле?

Сначала прочитал посты Herb's Sutters GotW, касающиеся pimpl в C++11:

У меня некоторые проблемы с пониманием решения, предложенного в GotW #101. Насколько я могу понять, все проблемы, с трудом решенные в GotW #100, вернулись с новой силой:

  • Члены pimpl являются внестрочными шаблонами, и их определения не видны в месте использования (в определении класса class widget и неявно сгенерированных специальных функциях-членах widget). Явных инстанцирований также нет. Это приведет к неразрешенным внешним ошибкам при компоновке.

  • widget::impl все еще неполный в точке, где pimpl<:impl>::~pimpl() является инстанцированным определением (я не думаю, что он вообще инстанцирован, просто на него ссылаются). Поэтому std::unique_ptr<:impl>::~unique_ptr() вызывает delete на указателе на неполный тип, что приводит к неопределенному поведению, если widget::impl имеет нетривиальный деструктор.

Пожалуйста, объясните, что заставляет компилятор генерировать специальные члены в контексте, когда widget::impl является полным. Потому что я не могу понять, как это работает.


Если GotW #101 все еще требует явного определения widget::~widget() в файле реализации, где widget::impl является полным, то, пожалуйста, объясните комментарий "More Robust" (который @sehe процитировал в своем ответе).

Я смотрю на основное утверждение GotW #101 о том, что обертка "устраняет некоторые части boilerplate", что, как мне кажется (основываясь на остальной части параграфа), означает объявление и определение widget::~widget(). Так что, пожалуйста, не полагайтесь на это в своем ответе, в GotW #101 этого нет!


Херб, если ты заглянешь, пожалуйста, сообщи мне, можно ли вырезать и вставить код решения сюда для справки.

21
задан Ben Voigt 22 February 2012 в 17:02
поделиться