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