Здравствуйте, so5team, Вы писали:
S>Вот этот вариант, вроде бы, работает вне зависимости от версии компилятора:
Вот, пытался понять суть все-таки, т.е. понять как там внутри unique_ptr устроена проверка и почему этой проверке важно отличать конструктор по умолчанию от пустого.
Такой код:
template <class _Ty>
struct default_delete2;
template <class _Ty, class _Dx = default_delete2<_Ty>>
class unique_ptr2;
template <class _Ty, class _Dx>
class unique_ptr2 {
};
template <class _Ty>
struct default_delete2 { // default deleter for unique_ptr
constexpr default_delete2() noexcept = default;
inline void operator()(_Ty* _Ptr) const noexcept
{
static_assert(0 < sizeof(_Ty), "can't delete an incomplete type");
delete _Ptr;
}
};
Это типа аналог урезанный unique_ptr — называется unique_ptr2. Но от него нужна только эта проверка.
По идее как-то должен вызываться оператор скобок () для default_delete (у нас default_delete2). Но где он вызывается — что-то я не увидел в коде.
Re[34]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, rg45, Вы писали:
R>Да пожалуйста (как же ты надоел):
Хотел еще узнать, знаете ли вы как оно внутри работает?
Там примерно такой код:
template <class _Ty>
struct default_delete2;
template <class _Ty, class _Dx = default_delete2<_Ty>>
class unique_ptr2;
template <class _Ty, class _Dx>
class unique_ptr2 {
};
template <class _Ty>
struct default_delete2 { // default deleter for unique_ptr
constexpr default_delete2() noexcept = default;
inline void operator()(_Ty* _Ptr) const noexcept
{
static_assert(0 < sizeof(_Ty), "can't delete an incomplete type");
delete _Ptr;
}
};
Срабатывает static_assert в операторе (). Но как-то не увидел где вызывается этот оператор — скобок, как сделать мин. функционал, который приведет к тому же эффекту?
Здравствуйте, so5team, Вы писали:
S>"Один дурак может вдесятеро больше задать вопросов, чем десять мудрецов способны разрешить" (с)
А что там реально сложно понять? Вы понимаете же как оно внутри работает и почему такой static_assert сработал? Или просто сталкивались на практике с этом не вникая в глубинную причину?
Re[32]: Ошибка, если конструктор определен в h-файле (этюд?)
S>Срабатывает static_assert в операторе (). Но как-то не увидел где вызывается этот оператор — скобок, как сделать мин. функционал, который приведет к тому же эффекту?
Можно, конечно, чуть позже сделаем.
Вкратце: весь фокус здесь в том, в какой момент происходит инстанцирование класса делетера. А происходит оно при первом использовании — т.е. в точке инициализации умного указателя. А точка инициализации умного указателя находится в конструкторе класса (в нашем примере это был конструктор класса Class1). Когда конструктор определен в теле класса, в точке инстанцирования делетера определение класса Class1::Impl скрыто от компилятора и происходит ошибка компиляции (срабатывает static_assert). Когда же мы переносим конструктор в cpp, ситуация меняется — здесь уже видно определение класса Impl, и все компилируется успешно.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[32]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, Shmj, Вы писали:
S>Хотел еще узнать, знаете ли вы как оно внутри работает?
Там все несложно: объект делетера передается параметром по умолчанию в конструктор умного указателя и сохраняется в объекте умного указателя. А потом этот делетер вызызывается в деструкторе умного указателя.
И тут есть один не очень очевидный, но важный момент, который нужно понимать. В зависимости от реализации, вызова делетера может и не произойти — в деструкторе класса умного указателя может находиться проверка — вызывать делетер только при условии, если указатель ненулевой. НО! Эта проверка происходит во время выполнения. А static_assert срабатывает во время компиляции. Улавливаешь момент? Произодет вызов делетера или нет, во время компиляции не известно, но компилятор видит, что существует по крайней мере одна веточка в ветвлении программы, когда делетер МОЖЕТ быть вызван. Поэтому компилятор вынужден инстанцировать функцию-член operator() делетера. Вот при этом инстанцировании и срабатывает static_assert. Понятно объяснил?
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Shmj, Вы писали:
S>Хотел еще узнать, знаете ли вы как оно внутри работает? S>Срабатывает static_assert в операторе (). Но как-то не увидел где вызывается этот оператор — скобок, как сделать мин. функционал, который приведет к тому же эффекту?
Ну вот тебе эскиз реализации. Понятное дело, что все очень упрощенно, это лишь для понимания принципа, как оно там внутри устроено:
Здравствуйте, Shmj, Вы писали:
S>А что там реально сложно понять?
Нет.
S>Вы понимаете же как оно внутри работает и почему такой static_assert сработал?
Да.
S>Или просто сталкивались на практике с этом не вникая в глубинную причину?
Shmj, большинства ваших тупых вопросов не возникло бы, если бы вы взяли на себя труд погрузиться в C++ нормально. Например, проштудировали бы "Язык программирования C++" от Страуструпа и повыполняли бы упражнения, которые он дает в конце каждой главы.
Вместо этого вы пытаетесь воспользоваться помощью форумчан для того, чтобы вам задарма влили в голову знания, которые приобретаются самостоятельно (за счет учебы и практики). Закономерным итогом становится то, что "ваши рыжие кудри примелькаются, и вас просто начнут бить" (с) Но, поскольку дать вам по шее в прямом смысле не получится, остается высказывать вам свое "фи" доступными на форуме способами.
Почему этого еще не начал делать rg45 для меня загадка. Вот уж, поистине, святой человек.
Re[37]: Ошибка, если конструктор определен в h-файле (этюд?)
Здравствуйте, so5team, Вы писали:
S>Почему этого еще не начал делать rg45 для меня загадка. Вот уж, поистине, святой человек.
Мне показалось, что, в кои-то веки, он в чем-то пытается самостоятельно разобраться. Пускай даже подходя не совсем с нормальной стороны, но это были уже действительно вопросы по существу, а не вот эти его: "Я понял, есть два вида С++". Ну и на радостях у меня возникло желание помочь.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[12]: Ошибка, если конструктор определен в h-файле (этюд?)