LINUX.ORG.RU

А ты Страуструпу письмо напиши :-) Он мужик интеллигентный, думаю ответит.

anonymous
()

объясню, давай еще раз вопрос в этот тред :) а-то в том я не понял, что именно тебе не понятно... вроде нормально отвечали

anonymous
()

Блин, ничего мне не понятно. Такой я тупой.
Вопрос звучал так: почему для присваивания типа
auto_ptr<T> my;
my = new T;
необходим оператор присваивания, принимающий структуру 
auto_ptr_ref, если и она и сам auto_ptr конструируются 
одинаково из T*?

JekLove
() автор топика

Блин, ничего мне не понятно. Такой я тупой.
Вопрос звучал так: почему для присваивания типа
auto_ptr<T> my;
my = new T;
необходим оператор присваивания, принимающий структуру 
auto_ptr_ref, если и она и сам auto_ptr конструируются 
одинаково из T*?

JekLove
() автор топика

Блин, ничего мне не понятно. Такой я тупой.
Вопрос звучал так: почему для присваивания типа
auto_ptr<T> my;
my = new T;
необходим оператор присваивания, принимающий структуру 
auto_ptr_ref, если и она и сам auto_ptr конструируются 
одинаково из T*?

JekLove
() автор топика

интересная постановка вопроса :)

ну тогда по порядку: для любых A и B

A=B значит A.operator=(B), ну и возможно неявные преобразования типов.

A a=B; значит a.A(B) то-есть a конструируется из B, как и в A a(B);

ключевое слово explicit значит что конструктор не учавствует в неявных преобразованиях и его нужно явно указывать, напр auto_ptr<int> ap(new int(0xff));

далее, у auto_ptr есть конструктор из указателя, из auto_ptr_ref, копирующий конструктор, оператор присваивания из auto_ptr, и операторы преобразования типа в auto_ptr_ref и в auto_ptr для другого параметра шаблона.

в итоге, auto_ptr<T>::operator=(T*) нету, видимо так и задумывалось, чтобы только явно их конструировать и потом передавать/присваивать с передачей "ответственности" за удаление объекта,

когда ты делаешь my = new T; нужного оператора нет

правильное использование auto_ptr<T> my(new T); потом можно использовать как указатель

так понятнее?

HTH

anonymous
()

Хокей, я понял. Т.е. вроде как мешает explicit, да? (Я прекрасно знаю, что он значит) Интересно, что если это слово убрать, ничегошеньки не изменится... хех.

JekLove
() автор топика

ну нету у меня щаз 3.0.3 gcc, брось хоть сюда, что он говорит в подробностях?

anonymous
()

Пожалуйста.
Код такой:

auto_ptr<int> t;
t = new int;

(Я удалил в auto_ptr все методы, связанные со структурой
auto_ptr_ref и саму эту структуру и, конечно, explicit)

p.cc: In function `int main()':
p.cc:14: no match for `auto_ptr<int>& = int*' operator
mem.h:25: candidates are: auto_ptr<_Tp>& 
   auto_ptr<_Tp>::operator=(auto_ptr<_Tp>&) [with _Tp = int]

JekLove
() автор топика

Эх, черт, у меня нет gcc более старой версии :(( Может, кто проверит на стареньком эту фишку? Хотя в коде класса auto_ptr перед тем оператором присваивания, принимающим структуру auto_ptr_ref, имеется очень интересный комментарий: // According to the C++ standard, these conversions are required. Most // present-day compilers, however, do not enforce that equirement---and, // in fact, most present-day compilers do not support the language // features that these conversions rely on. Что бы это значило??

JekLove
() автор топика

#include "memory.h"
auto_ptr<int> my(new int);
my=new int;

если без explicit то: g++ --version; g++ -W -Wall -c auto_ptr.cc
2.95.4
auto_ptr.cc: In function `int main()':
auto_ptr.cc:9: initialization of non-const reference type `class auto_ptr<int> &'
auto_ptr.cc:9: from rvalue of type `auto_ptr<int>'
memory.h:25: in passing argument 1 of `auto_ptr<int>::operator =(auto_ptr<int> &)'

если с explicit то:
auto_ptr.cc: In function `int main()':
auto_ptr.cc:9: no match for `auto_ptr<int> & = T *&'
memory.h:25: candidates are: class auto_ptr<int> & auto_ptr<int>::operator =(auto_ptr<int> &)

две большие разницы.

anonymous
()

да, щаз таки выкачаю gcc-3.0.4, соберу и и попробую специально для некоторых земляков :)

anonymous
()

попробуем по другому?

есть конструкторы explicit auto_ptr(T*); auto_ptr(auto_ptr&); //важно, что НЕ const auto_ptr&

есть оператор "передачи ответственности" auto_ptr& operator=(auto_ptr<T1>&);

если мы пишем что-то вроде auto_ptr<T> ap; ap=new T;

нам нужно неявно создать временный объект auto_ptr<T>, конструктор explicit auto_ptr(T*) не рассматривается, т.к. explicit.

если убираем explicit, то он принимается во внимание, но gcc не хочет передавать этот временный объект по неконстантной ссылке. мол типа как-то странно передавать временный объект в функцию/оператор который его намеренно модифицирует, значит полагается на результат изменения

так понятнее?

HTH

anonymous
()

так вот, скачал, собрал gcc-3.0.4, результаты:

#include <iostream>
#include <iomanip>
#include <memory.h>

int main(void)
{
        typedef int T;
        std::auto_ptr<T> my(new T(1));
        T* p=new T(11);
        my=p;
        my=new T(111);

        std::cout <<  " " << *my << std::endl;
        return 0;
}

странно наверное, но все работает :)
export CC=/usr/local/bin/gcc
export LD_LIBRARY_PATH=/usr/local/lib
$CC -W -Wall auto_ptr.cc -lstdc++
ни ошибок ни предупреждений...

почему 2.95.x себя ведет так, как я написал выше --- вопрос,
будем думать...

теперь надеюсь все понятно? :) если нет --- пиши

HTH

anonymous
()

ой, опечатался, естественно надо #include <memory>, а не #include<memory.h>

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.