Здравствуйте, Shmj, Вы писали:
S>S>template <class _Ty>
S>struct default_delete2 { // default deleter for unique_ptr
S> constexpr default_delete2() noexcept = default;
S> inline void operator()(_Ty* _Ptr) const noexcept
S> {
S> static_assert(0 < sizeof(_Ty), "can't delete an incomplete type");
S> delete _Ptr;
S> }
S>};
S>
S>Срабатывает static_assert в операторе (). Но как-то не увидел где вызывается этот оператор — скобок, как сделать мин. функционал, который приведет к тому же эффекту?
Можно, конечно, чуть позже сделаем.
Вкратце: весь фокус здесь в том, в какой момент происходит инстанцирование класса делетера. А происходит оно при первом использовании — т.е. в точке инициализации умного указателя. А точка инициализации умного указателя находится в конструкторе класса (в нашем примере это был конструктор класса Class1). Когда конструктор определен в теле класса, в точке инстанцирования делетера определение класса Class1::Impl скрыто от компилятора и происходит ошибка компиляции (срабатывает static_assert). Когда же мы переносим конструктор в cpp, ситуация меняется — здесь уже видно определение класса Impl, и все компилируется успешно.