Почему auto_ptr <T> не имеет оператора!()?
Название в значительной степени подводит итог моему вопросу. Почему не может быть сделано следующее, чтобы проверить нулевой указатель?
auto_ptr<char> p( some_expression );
// ...
if ( !p ) // error
Это нужно сделать вместо:
if ( !p.get() ) // OK
Почему auto_ptr<T>
просто не имеет operator!()
?
Ответы
Ответ 1
Кажется, была ошибка в его дизайне. Это будет исправлено в С++ 0x. unique_ptr
(замена для auto_ptr
) содержит explicit operator bool() const;
Цитата из нового стандарта С++:
Шаблон класса auto_ptr устарел. [Примечание. Шаблон класса unique_ptr (20.9.10) предоставляет лучшее решение. -end note]
Некоторые уточнения:
Q: Что случилось с a.get() == 0
?
A: В a.get()==0
ничего не получается, но интеллектуальные указатели позволяют работать с ними, поскольку они являются настоящими указателями. Дополнительный operator bool()
дает вам такой выбор. Я думаю, что настоящая причина принятия auto_ptr
устарела - это не имеет интуитивного дизайна. Но operator bool
для unique_ptr
в новом стандарте означает, что нет причин не иметь его.
Ответ 2
Проще говоря, он должен иметь operator !()
. auto_ptr
не очень хорошо спроектированный контейнер. Интеллектуальные указатели в boost имеют оператор преобразования operator bool()
, который можно отменить с помощью operator !()
. Это позволит вашему if(!p)
скомпилировать и работать как ожидалось.
Ответ 3
Существует проблема с булевым преобразованием. Это позволяет синтаксису почти всегда болеть.
Существует, к счастью, решение: идиома Safe Bool.
Проблема с преобразованием в bool
заключается в том, что неявное преобразование является опасным.
std::auto_ptr<T> p = ..., q = ....;
if (p < q) // uh ?
Следовательно, operator bool() const
является мерзостью. Либо вы предоставляете явный метод... или вы используете безопасную идиому bool.
Идея идиомы состоит в том, чтобы дать вам экземпляр типа с довольно минимальным подмножеством операций и почти не имеет случая, когда неявное преобразование вызовет у вас проблемы. Это делается с помощью указателя на функцию-член.
Операции вроде if (p)
и if (!p)
тогда имеют смысл, но if (p < q)
не скомпилируется.
Прочитайте ссылку полностью для полного решения, и вы поймете, почему было хорошей идеей не иметь operator bool() const
.
Ответ 4
Я подозреваю, потому что ожидалось, что переход вокруг auto_ptr
к null будет редким случаем, чтобы избежать добавления дополнительного интерфейса и сделать его явным при фактической проверке нулевого значения.