#include <memory>
using namespace std;
auto_ptr<int> get()
{
return auto_ptr<int>(new int);
}
int main()
{
auto_ptr<int> p;
p = get(); // (1)
}
Далее, вроде результат возврата функции (в данном случае) — rvalue. Следовательно, на него нельзя делать неконстантную ссылку. Следовательно, нельзя присвоить в месте, помеченном (1) (у auto_ptr-а присваивание, как и конструктор копии, требует именно неконстантную ссылку). Причем gcc 2.95 так, собственно, и говорит.
Получаем, что auto_ptr нельзя использовать для возврата указателя из функции. Тем не менее, постоянно упоминается, что для этого, собственно, он и применяется. Где я не прав?
WF>Далее, вроде результат возврата функции (в данном случае) — rvalue. Следовательно, на него нельзя делать неконстантную ссылку.
Ну и что. Ты же не ссылку делаешь на него, а вызываешь оператор присваивания. Так как справа у тебя неконстантный объект, то все нормально.
WF>Причем gcc 2.95 так, собственно, и говорит.
Не знаю, как gcc, а VC отлично компилирует.
Здравствуйте, Vamp, Вы писали:
WF>>Далее, вроде результат возврата функции (в данном случае) — rvalue. Следовательно, на него нельзя делать неконстантную ссылку. V>Ну и что. Ты же не ссылку делаешь на него, а вызываешь оператор присваивания.
W> Далее, вроде результат возврата функции (в данном случае) — rvalue.
Верно.
W> Следовательно, на него нельзя делать неконстантную ссылку.
Тоже верно.
W> Следовательно, нельзя присвоить в месте, помеченном (1)
А вот это не соответствует действительности.
W> (у auto_ptr-а присваивание, как и конструктор копии, требует именно неконстантную ссылку).
В новой версии std::::auto_ptr<>, вошедшей в стандарт, есть специальный оператор присваивания
(равно как и соответствующий конструктор "копирования"), который принимает не std::auto_ptr<>&,
а std::auto_ptr<>::auto_ptr_ref<>. В свою очередь, const std::auto_ptr<> "умеет" приводиться
к std::auto_ptr<>::auto_ptr_ref<>, через который и осуществляется "копирование".
W> Причем gcc 2.95 так, собственно, и говорит.
Этот компилятор, как и некоторые другие старые компиляторы, содержит устаревшую реализацию std::auto_ptr.
Posted via RSDN NNTP Server 1.7 "Bedlam"
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Возврат auto_ptr из функции
От:
Аноним
Дата:
22.09.03 12:22
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>В новой версии std::::auto_ptr<>, вошедшей в стандарт,
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>>> В новой версии std::::auto_ptr<>, вошедшей в стандарт,
>> Это, то есть, вошедшей в TC?
ПК>Нет, именно в стандарт. GC++2.95, как и VC++6.0, включает достандартную реализацию.
А где же в стандарте оператор присваивания, принимающий std::auto_ptr<>::auto_ptr_ref<>?
Здравствуйте, Вы писали:
>>> Это, то есть, вошедшей в TC?
ПК>> Нет, именно в стандарт. GC++2.95, как и VC++6.0, включает ПК>> достандартную реализацию.
> А где же в стандарте оператор присваивания, принимающий > std::auto_ptr<>::auto_ptr_ref<>?
Здравствуйте, Аноним, Вы писали:
ПК>>>> В новой версии std::::auto_ptr<>, вошедшей в стандарт,
>>> Это, то есть, вошедшей в TC?
ПК>>Нет, именно в стандарт. GC++2.95, как и VC++6.0, включает достандартную реализацию.
А>А где же в стандарте оператор присваивания, принимающий std::auto_ptr<>::auto_ptr_ref<>?
Оператор присваивания сделать "забыли". Есть только конструктор конверсии.
Забытый оператор присваивания — дефект стандарта. Но как правило реализации все равно его включают.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Здравствуйте, WFrag, Вы писали:
[]
ПК>В новой версии std::::auto_ptr<>, вошедшей в стандарт, есть специальный оператор присваивания ПК>(равно как и соответствующий конструктор "копирования"), который принимает не std::auto_ptr<>&, ПК>а std::auto_ptr<>::auto_ptr_ref<>. В свою очередь, const std::auto_ptr<> "умеет" приводиться ПК>к std::auto_ptr<>::auto_ptr_ref<>, через который и осуществляется "копирование".
Здравствуйте, MaximE, Вы писали:
ME>Здравствуйте, Павел Кузнецов, Вы писали:
ПК>>Здравствуйте, WFrag, Вы писали:
ME>[]
ПК>>В новой версии std::::auto_ptr<>, вошедшей в стандарт, есть специальный оператор присваивания ПК>>(равно как и соответствующий конструктор "копирования"), который принимает не std::auto_ptr<>&, ПК>>а std::auto_ptr<>::auto_ptr_ref<>. В свою очередь, const std::auto_ptr<> "умеет" приводиться ПК>>к std::auto_ptr<>::auto_ptr_ref<>, через который и осуществляется "копирование".
ME>В действительности, эти вещи не так просты. Даже Саттер не мог въехать — What is auto_ptr_ref for? <br />
<span class='lineQuote level1'>ME></span>
Саттер тогда не подумал о том, что copy-initialization в ситуации, когда cv-unqualified типы левой и правой части совпадают является особым случаем, который обрабатывается отлично от случая, когда cv-unqualified типы левой и правой части не совпадают. В случае совпадения типов, код автоматически рассматривается, как эквивалентная direct-initialization. При этом одно из приведений типа становится явным, и остается только одно неявное приведение.
Здравствуйте, Андрей Тарасевич, Вы писали:
ME>>В действительности, эти вещи не так просты. Даже Саттер не мог въехать — What is auto_ptr_ref for? <br />
<span class='lineQuote level2'>ME>></span>
АТ>Саттер тогда не подумал о том, что copy-initialization в ситуации, когда cv-unqualified типы левой и правой части совпадают является особым случаем, который обрабатывается отлично от случая, когда cv-unqualified типы левой и правой части не совпадают. В случае совпадения типов, код автоматически рассматривается, как эквивалентная direct-initialization. При этом одно из приведений типа становится явным, и остается только одно неявное приведение.
Здравствуйте, Андрей Тарасевич, Вы писали:
ME>>В действительности, эти вещи не так просты. Даже Саттер не мог въехать — What is auto_ptr_ref for? <br />
<span class='lineQuote level2'>ME>></span>
АТ>Саттер тогда не подумал о том, что copy-initialization в ситуации, когда cv-unqualified типы левой и правой части совпадают является особым случаем, который обрабатывается отлично от случая, когда cv-unqualified типы левой и правой части не совпадают. В случае совпадения типов, код автоматически рассматривается, как эквивалентная direct-initialization. При этом одно из приведений типа становится явным, и остается только одно неявное приведение.
Да, похоже что так. Это сообщение в вышеупомянутом топике выглядит лучшим объяснением, особенно вот эта часть:
in [decl.init] it says in the description of copy-initialization:
"If [the type of the initializer is T] constructors are considered."
.. which again effectively reduces the copy-initialization case to the
direct-initialization case. Only if the condition is false, a
conversion to T is attempted.
Note that _all_ constructors are considered — there is no mention of
the _copy_ constructor in this context.