Подтвердить что ты не робот

Могу ли я назначить 0 для shared_ptr? Зачем?

Я понял, что в GCC 4.7 реализованы следующие компиляции:

#include <memory>

int main() {
    std::shared_ptr<int> p;
    p = 0;
}

Однако нет оператора присваивания из int или из int*, и нет никакого неявного конструктора из int или int*. Существует конструктор из int*, но этот явно. Я проверил стандартную реализацию библиотеки, и конструктор действительно явный, и никаких подозрительных операторов присваивания не видно.

Является ли программа действительно хорошо сформированной или GCC возится со мной?

4b9b3361

Ответ 1

Причиной этого является короткая цитата из стандарта:

§4.10 [conv.ptr] p1

Константа нулевого указателя - это выражение integer constant (5.19) prvalue целочисленного типа , которое оценивается до нуля или prvalue типа std::nullptr_t. [...] Константа нулевого указателя интегрального типа может быть преобразована в prvalue типа std::nullptr_t. [...]

И тот факт, что std::shared_ptr имеет неявный конструктор из std::nullptr_t:

§20.7.2.2 [util.smartptr.shared] p1

constexpr shared_ptr(nullptr_t) : shared_ptr() { }

Это также допускает такие странности:

#include <memory>

void f(std::shared_ptr<int>){}

int main(){
  f(42 - 42);
}

Пример в реальном времени.

Ответ 2

Вы можете назначить общий указатель другому экземпляру общего указателя. Назначение типа, которым владеет shared_pointer, невозможно. Afaik это единственная перегрузка для оператора:

shared_ptr& operator=(const shared_ptr& r);

То, что вы делаете, это присвоение указателю 0 (которое в этом случае равно NULL), а не значение типа. В этот момент кода вы не инициализированы.