На этом шаге мы рассмотрим различные преобразования, используемые в операциях присваивания и копирования.
Прочие члены класса auto_ptr (вспомогательный тип auto_ptr_ref и использующие его функции) реализуют довольно хитрые преобразования, позволяющие выполнять операции копирования и присваивания только с неконстантными экземплярами auto_ptr. Ниже приводится краткое пояснение. Необходимо обеспечить выполнение двух требований.
Поскольку тип auto_ptr является классом, это должно делаться с применением конструктора.
Обычный копирующий конструктор может скопировать r-значение, но для этого его параметр должен быть объявлен в виде ссылки на константный объект. В случае использования обычного конструктора для копирования auto_ptr нам придется объявить переменную класса, содержащую фактический указатель, изменяемой, чтобы ее можно было модифицировать в копирующем конструкторе. Но тогда вы сможете написать код, который копирует объекты auto_ptr, объявленные константными; передача права владения противоречит объявлению этих объектов константными.
Возможен и другой вариант - найти механизм, который бы позволял преобразовать r-значение в l-значение. Простая операторная функция преобразования к ссылочному типу не подойдет, поскольку такие функции никогда не вызываются для преобразования объекта к его собственному типу (вспомните, что атрибут "ссылочности" не является частью типа). По этой причине был введен класс auto_ptr_ref, обеспечивающий механизм преобразования в l-значение. Работа этого механизма основана на различиях между перегрузкой (overloading) и правилах идентификации аргументов в шаблонах. Эти различия слишком тонки, чтобы использовать их в качестве общего инструмента программирования, но в данном случае они обеспечивают правильную работу класса auto_ptr.
Не удивляйтесь, если ваш компилятор еще не различает константные и неконстантные объекты auto_ptr. Также учтите, что в этом случае работа с auto_ptr требует еще большей осторожности - малейшая невнимательность легко приводит к непредвиденной передаче прав владения.
На следующем шаге мы приведем пример реализации класса auto_ptr.