В std::auto_ptr определен лишний метод?
От: NightWind Россия  
Дата: 29.01.09 22:53
Оценка:
Здравствуйте!
Посмотрел я на каноническое определение std::auto_ptr [20.4.5]:
namespace std {
   template <class Y> struct auto_ptr_ref {};
   
   template<class X> class auto_ptr {
   public:
      typedef X element_type;
      // 20.4.5.1 construct/copy/destroy:
      explicit auto_ptr(X* p =0) throw();
      auto_ptr(auto_ptr&) throw();
      template<class Y> auto_ptr(auto_ptr<Y>&) throw();
      auto_ptr& operator=(auto_ptr&) throw();
      template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
      auto_ptr& operator=(auto_ptr_ref<X> r) throw();
      ~auto_ptr() throw();
      // 20.4.5.2 members:
      X& operator*() const throw();
      X* operator->() const throw();
      X* get() const throw();
      X* release() throw();
      void reset(X* p =0) throw();
      // 20.4.5.3 conversions:
      auto_ptr(auto_ptr_ref<X>) throw();
      template<class Y> operator auto_ptr_ref<Y>() throw();
      template<class Y> operator auto_ptr<Y>() throw();
};
}

и не смог понять зачем нужен следующий метод:
template<class Y> operator auto_ptr<Y>() throw();


Приведите, пожалуйста, пример, который перестаёт компилироваться (работать) если этот метод убрать.
Заранее благодарен.
Re: В std::auto_ptr определен лишний метод?
От: Erop Россия  
Дата: 29.01.09 23:23
Оценка:
Здравствуйте, NightWind, Вы писали:

NW>Приведите, пожалуйста, пример, который перестаёт компилироваться (работать) если этот метод убрать.


class A {
// ...
public:
    virtual ~A() {}
};

class B : public A {
// ...
};

std::auto_ptr<B> foo();
inline std::auto_ptr<A> bar()
{
    return foo();
}



NW>Заранее благодарен.


Для спасибо тут есть кнопки...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: В std::auto_ptr определен лишний метод?
От: NightWind Россия  
Дата: 29.01.09 23:29
Оценка:
Здравствуйте, Erop, Вы писали:

E>std::auto_ptr<B> foo();


А в чём прикол comeau никак не компилит?
namespace std {
   template <class Y> struct auto_ptr_ref {};
   
   template<class X> class auto_ptr {
   public:
      typedef X element_type;
      // 20.4.5.1 construct/copy/destroy:
      explicit auto_ptr(X* p =0) throw();
      auto_ptr(auto_ptr&) throw();
      template<class Y> auto_ptr(auto_ptr<Y>&) throw();
      auto_ptr& operator=(auto_ptr&) throw();
      template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
      auto_ptr& operator=(auto_ptr_ref<X> r) throw();
      ~auto_ptr() throw();
      // 20.4.5.2 members:
      X& operator*() const throw();
      X* operator->() const throw();
      X* get() const throw();
      X* release() throw();
      void reset(X* p =0) throw();
      // 20.4.5.3 conversions:
      auto_ptr(auto_ptr_ref<X>) throw();
      template<class Y> operator auto_ptr_ref<Y>() throw();
      template<class Y> operator auto_ptr<Y>() throw();
};
}

class A {
// ...
public:
    virtual ~A() {}
};

class B : public A {
// ...
};

std::auto_ptr<B> foo();
inline std::auto_ptr<A> bar()
{
    return foo();
}



E>Для спасибо тут есть кнопки...

И впрямь, но жать мы их пока повременим
Re: В std::auto_ptr определен лишний метод?
От: Bell Россия  
Дата: 30.01.09 03:48
Оценка:
Здравствуйте, NightWind, Вы писали:

Вот здесь можно почитать об этой проблеме:
здесь
здесь
здесь
Любите книгу — источник знаний (с) М.Горький
Re[2]: В std::auto_ptr определен лишний метод?
От: NightWind Россия  
Дата: 30.01.09 10:06
Оценка:
Здравствуйте, Bell, Вы писали:

B>Вот здесь можно почитать об этой проблеме:

B>...

Да я эти ссылки видел, на них Мейерс в своей статье ссылается.

Меня же совсем другое интересует: Зачем там всё таки последний метод?
Re: В std::auto_ptr определен лишний метод?
От: Roman Odaisky Украина  
Дата: 30.01.09 13:11
Оценка:
Здравствуйте, NightWind, Вы писали:

NW>не смог понять зачем нужен следующий метод:

NW>template<class Y> operator auto_ptr<Y>() throw();

Чтобы преобразовывать rvalue типа std::auto_ptr<Derived> к std::auto_ptr<Base>.
До последнего не верил в пирамиду Лебедева.
Re[2]: В std::auto_ptr определен лишний метод?
От: NightWind Россия  
Дата: 30.01.09 13:46
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Чтобы преобразовывать rvalue типа std::auto_ptr<Derived> к std::auto_ptr<Base>.


Ладно, повторю оригинальный вопрос:

Приведите, пожалуйста, пример, который перестаёт компилироваться (работать) если этот метод убрать.


Если такого примера нет => метод лишний.
Re: В std::auto_ptr определен лишний метод?
От: igna Россия  
Дата: 30.01.09 16:10
Оценка: :)
Здравствуйте, NightWind, Вы писали:

NW>Приведите, пожалуйста, пример, который перестаёт компилироваться (работать) если этот метод убрать.


Пообещаешь наивысшую оценку, приведу.
Re[2]: В std::auto_ptr определен лишний метод?
От: NightWind Россия  
Дата: 30.01.09 16:47
Оценка: :)
Здравствуйте, igna, Вы писали:

I>Пообещаешь наивысшую оценку, приведу.


Торжественно обещаю, если он не будет вариацией вот этого:

  std::auto_ptr<int> v;
  v.operator auto_ptr<int>();


Re[3]: В std::auto_ptr определен лишний метод?
От: Roman Odaisky Украина  
Дата: 30.01.09 16:59
Оценка: 7 (2)
Здравствуйте, NightWind, Вы писали:

NW>Приведите, пожалуйста, пример, который перестаёт компилироваться (работать) если этот метод убрать.


#include <memory>

struct base
{
};

struct derived: base
{
};

int main()
{
    std::auto_ptr<base> const& test = std::auto_ptr<derived>();
}
До последнего не верил в пирамиду Лебедева.
Re[4]: В std::auto_ptr определен лишний метод?
От: NightWind Россия  
Дата: 30.01.09 17:04
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>
RO>    std::auto_ptr<base> const& test = std::auto_ptr<derived>();
RO>

Здорово! Спасибо!
Re: В std::auto_ptr определен лишний метод?
От: dmitry.maystrenco  
Дата: 30.01.09 17:07
Оценка:
Здравствуйте, NightWind, Вы писали:

NW>Здравствуйте!

NW>Посмотрел я на каноническое определение std::auto_ptr [20.4.5]:
NW>
NW>namespace std {
NW>   template <class Y> struct auto_ptr_ref {};
   
NW>   template<class X> class auto_ptr {
NW>   public:
NW>      typedef X element_type;
NW>      // 20.4.5.1 construct/copy/destroy:
NW>      explicit auto_ptr(X* p =0) throw();
NW>      auto_ptr(auto_ptr&) throw();
NW>      template<class Y> auto_ptr(auto_ptr<Y>&) throw();
NW>      auto_ptr& operator=(auto_ptr&) throw();
NW>      template<class Y> auto_ptr& operator=(auto_ptr<Y>&) throw();
NW>      auto_ptr& operator=(auto_ptr_ref<X> r) throw();
NW>      ~auto_ptr() throw();
NW>      // 20.4.5.2 members:
NW>      X& operator*() const throw();
NW>      X* operator->() const throw();
NW>      X* get() const throw();
NW>      X* release() throw();
NW>      void reset(X* p =0) throw();
NW>      // 20.4.5.3 conversions:
NW>      auto_ptr(auto_ptr_ref<X>) throw();
NW>      template<class Y> operator auto_ptr_ref<Y>() throw();
NW>      template<class Y> operator auto_ptr<Y>() throw();
NW>};
NW>}
NW>

NW>и не смог понять зачем нужен следующий метод:
NW>
NW>template<class Y> operator auto_ptr<Y>() throw();
NW>


NW>Приведите, пожалуйста, пример, который перестаёт компилироваться (работать) если этот метод убрать.

NW>Заранее благодарен.

На счет примера, трудно предложить, а идея этого оператора, достаточна проста, если обрать внимание, то очень многие классы STL изобилуют в той или иной мере такой конструкцией, в шаблонных классах заложена архитектура автоматической специализации если в качеcтве приемника или источника выступает близкий по сигнатуре класс, например был изначально std::auto_ptr<int> а мы его присвоим std::auto_ptr<long>, для нас разницы нет, для компилятора разница сушественная, если потребитель кода будет специализировать класс, например
template<> auto_ptr<long> auto_ptr<int>::operator auto_ptr<long>()
...

в этом случае он сможете определить особенное поведение класса auto_ptr для особенных случаев
Re[2]: В std::auto_ptr определен лишний метод?
От: igna Россия  
Дата: 30.01.09 17:24
Оценка:
Здравствуйте, dmitry.maystrenco, Вы писали:

DM>например был изначально std::auto_ptr<int> а мы его присвоим std::auto_ptr<long>


Ты не ошибся? Присвоить указатель на int указалю на long?
Re[3]: В std::auto_ptr определен лишний метод?
От: dmitry.maystrenco  
Дата: 30.01.09 19:29
Оценка:
Здравствуйте, igna, Вы писали:

I>Здравствуйте, dmitry.maystrenco, Вы писали:


DM>>например был изначально std::auto_ptr<int> а мы его присвоим std::auto_ptr<long>


I>Ты не ошибся? Присвоить указатель на int указалю на long?


Выбор int и long не самый удачный, по крайней мере в auto_ptr, для auto_ptr, прокатит без проблем в том случае если классы используемые в параметрах являются элементами в иерархии, причем только с верху вниз, из-за того, что в конструкторе копирования используется присвоение одного указателя другому (настоящих)

class A
{
};

class B : public A
{
};

...

std::auto_ptr<B> b(new B);
std::auto_ptr<A> a = b;

работает, тогда как

std::auto_ptr<A> a(new A);
std::auto_ptr<B> b = a;

уже нет.

Забавно другое, если написать по аналогии с auto_ptr, реализацию:

template<typename _Ty> class A
{
public:
template<typename _Other> A(_Other& _Right)
{
printf("A normal\n");
}
};

class B
{
};

template<> template<> A<long>::A(B& _Right)
{
printf("A special for B\n");
}


то при

double d;
B b;

A<int> a(d);
A<long> c(b);

получаем такой вывод:

A normal
A special for B

и возвращаясь к auto_ptr если попытаться специализировать

namespace std
{
template<>
template<> auto_ptr<int>::auto_ptr(auto_ptr<long>& r)
{
}
}

то компайлер упорно не видит специализации в данном случае, вот в чем прикол.
а на счет int* к long*, это своеобразно, но не так страшно (под AI32 мы ничего страшного не пытались делать )
Re[3]: В std::auto_ptr определен лишний метод?
От: Bell Россия  
Дата: 02.02.09 04:07
Оценка: 2 (1)
Здравствуйте, NightWind, Вы писали:

NW>Да я эти ссылки видел, на них Мейерс в своей статье ссылается.


NW>Меня же совсем другое интересует: Зачем там всё таки последний метод?


Ну так там ведь написано? Дефект 84 (здесь), давал возможность использования двух пользовательских преобразований при инициализации копированием. Это позволяло, в частности, компилировать пример, приведенный Erop-ом. Некоторые компиляторы до сих пор позволяют это делать — VC7.1, например, компилирует тот пример, и выдает только предупреждение:

warning C4927: illegal conversion; more than one user-defined conversion has been implicitly applied while calling the constructor

Любите книгу — источник знаний (с) М.Горький
Re[4]: В std::auto_ptr определен лишний метод?
От: NightWind Россия  
Дата: 02.02.09 11:55
Оценка:
Здравствуйте, Bell, Вы писали:

B>Ну так там ведь написано? Дефект 84 (здесь), давал возможность использования двух пользовательских преобразований при инициализации копированием.


Наверное самое важное, что без этого оператора компилировался бы следующий очень опасный код:

#include<memory>

struct B {};
struct D: B{};

void f( const std::auto_ptr<B> & )
{
//...
}

int main()
{
   std::auto_ptr<B> pB ( new D );
   std::auto_ptr<D> pD ( new D );

   f( pB );  
   //здесь pB жив и здоров 
   
   f( pD );  
   //здесь pD будет уничтожен!

   return 0;
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.