Re[6]: Wilson и auto_ptr
От: makes Россия  
Дата: 28.08.09 20:00
Оценка: +1
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Ты, я вижу, даже не попытался понять, кому и на что ответил saproj

СИЛЬНО извиняюсь

L_L>Возьми исходный пример автора топика, который...

а ты когда тему просматриваешь, наверное в начало не смотришь?..
(http://www.rsdn.ru/forum/cpp/3519299.1.aspx
Автор: makes
Дата: 28.08.09
)

L>И я не понимаю, это у меня с недосыпа с головой что-то и я не заметил чего-то, или тут, в этом флеймище люди о каком-то другом языке программирования рассуждают? Какие-то консты в параметры шаблона суют, еще чего-то, историю авто птр вспоминают...

я тоже не люблю усложнять
Re[4]: Wilson и auto_ptr
От: Николай Ивченков  
Дата: 28.08.09 20:57
Оценка: 6 (1)
Alexander G:

E>>А какой в этом смысл? Чем rvalue T* отличается от Т*const ?

AG>+
AG>тут та самая тонкость, что int * const f() и int * f() — одна и та же функция.

Это разные функции (в отличие от параметров, cv-квалификация типа возврата в типе функции никогда не удаляется). Причём стандарт в отношении результата вызова первой функции противоречив: с одной стороны он утверждает, что

"non-class rvalues always have cv-unqualified types" (3.10/9)

с другой — что

"The type of the function call expression is the return type of the statically chosen function" (5.2.2/3) — никакого упоминания о снятии cv-квалификации.

Вот такой пример

int * const f();

typedef char one[1];
typedef char two[2];

one &g(int const *);
template <class T>
    two &g(T &);

int main()
{
    char arr[sizeof g(f()) - 1];
}

успешно компилируется VC++ 8.0 и GNU C++ 4.1.2 (они считают, что f() имеет тип int * const, и выбирают вторую g) и не компилируется Intel C++ 11.0 и Comeau (они считают, что f() имеет тип int *, и выбирают первую g).
Re[5]: Wilson и auto_ptr
От: Programador  
Дата: 29.08.09 00:41
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Естественно, что над константой нет оператора автоинкремента.


К>Или ты хочешь сказать, что код

К>
К>int* p = auto_ptr<const int>(new int(123));
К>

К>удачно скомпилировался?!
К>Ну, выкини в топку свою версию STL, что ли.

Я написал в точности наоборот
const  std::auto_ptr<int>   ap(new int(123));
++*ap;

скомпилировался, автоинкримент не над константой и должен компилироватся. А operator* и get() почему компилируются неясно http://msdn.microsoft.com/en-us/library/b84a89af(VS.71).aspx не говорит что они константные. Правда const std::auto_ptr<int> не дает один ptr другому присвоить.
Re[2]: Wilson и auto_ptr
От: igna Россия  
Дата: 29.08.09 06:25
Оценка:
Здравствуйте, saproj, Вы писали:

S>В том, чтобы не дать такому коду скомпилиться:
S>const auto_ptr<int>ap(new int(123));
S>int*p=get_ptr(ap);


А зачем не дать? Собственно это и был мой вопрос. Смотри, ap у тебя объявлен как auto_ptr<int>, а не как auto_ptr<int const>, соответственно auto_ptr::get возвращает int*, а не int const*. Почему же get_ptr должен вводить дополнительное ограничение?

Да, не сочти за поучение, просто на всякий случай: const у auto_ptr в твоем примере делает константным указатель, а не то, на что тот указывает.
Re[2]: Wilson и auto_ptr
От: igna Россия  
Дата: 29.08.09 07:02
Оценка:
Здравствуйте, Кодт, Вы писали:

К>template<class T> T*       get_deep(T*&       p) { return p; }
К>template<class T> T const* get_deep(T*& const p) { return p; }
К>// и аналогично для умных

К>Если такой код встречается рядом — значит, разработчик молодец. Если нет — скорее всего, он чего-то недопонял.

Не встречается. Похоже, что auto_ptr кого хочешь запутает.

Здесь у того же автора перегрузки по константности нет, но auto_ptr зачем то должен быть неконстантным:

template <typename T>
inline T *get_ptr(std::auto_ptr<T> &p)
{
return p.get();
}


В исходниках его библиотеки сделано IMHO правильно:

/*
 * Thanks to:   Nevin Liber for spotting a mistake in the get_ptr
 *              definition.
 */

template <ss_typename_param_k T>
inline T *get_ptr(stlsoft_ns_qual_std(auto_ptr)<T> const& p)
{
     return p.get();
}


И в другой своей книге, Extended STL, Wilson тоже пишет правильно, если верить Safari Books Online:

template <typename T>
T* get_ptr(std::auto_ptr<T> const& p)
{
  return p.get();
}


Extended STL есть у меня на работе, в понедельник посмотрю.
Re[7]: Wilson и auto_ptr
От: Lorenzo_LAMAS  
Дата: 29.08.09 09:11
Оценка:
L_L>>Возьми исходный пример автора топика, который...
M>а ты когда тему просматриваешь, наверное в начало не смотришь?..
M>(http://www.rsdn.ru/forum/cpp/3519299.1.aspx
Автор: makes
Дата: 28.08.09
)


Да, теперь я сильно извиняюсь — не увидел твоего ответа.
Of course, the code must be complete enough to compile and link.
Re: Wilson и auto_ptr
От: alexeiz  
Дата: 29.08.09 21:04
Оценка: +2
Здравствуйте, igna, Вы писали:

I>Читаю книгу Matthew Wilson, Imperfect C++ и на странице 344...


I>В чем смысл этой перегрузки, почему вместо двух шаблонов не использовать один?:


Никакого смысла нет. (В начале я начал отвечать на этот пост, будучи уверенным, что смысл есть. Но по ходу того, как я пытался его объяснить, мне стало понятно, что никакого смысла нет.)

Wilson на этой странице пишет про так называемые шимы (shims). Shim — это, грубо говоря, простейший адаптер, который на короткое время сводит разные (но близкие по смыслу) интерфейсы к одному общему путём создания временного объекта.

Шимы могут быть различного характера:
* attribute — предостваляющие доступ к внутреннему свойству объекта
* control — позволяющие выполнить какое-нибудь действие над объектом
* conversion — переводящие к другому (не сходному) типу
и т.д.

get_ptr — это шим, предназначение которого — предоставлять доступ к внутреннему указателю для различных смарт поинтеров. В таком случае, вопрос нужно задать следующий: по смыслу (а не по техническим причинам), какой тип указателя содержится в (и нужно возвратить из) auto_ptr<T> и auto_ptr<T> const? Ясно, что тип указателя у них один и тот же — T*. Поэтому достаточно одной функции: T * get_ptr(auto_ptr<T> const &), а Wilson просто ошибся.
Re[2]: Wilson и auto_ptr
От: Chorkov Россия  
Дата: 31.08.09 08:21
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, igna, Вы писали:


I>>В чем смысл этой перегрузки, почему вместо двух шаблонов не использовать один?:


AG>Я считаю, просто дело привычки писать две версии в подобных случаях, написано неправильно "на автомате".

AG>Если бы это было задумано, const вариант был бы консистентен:

AG>
AG>template <typename T>
AG>inline T * const get_ptr(std::auto_ptr<T> const &p)
AG>{
AG>  return p.get();
AG>}
AG>



AG>или

AG>
AG>template <typename T>
AG>inline T const *get_ptr(std::auto_ptr<T const > &p)
AG>{
AG>  return p.get();
AG>}
AG>

AG>, но ни один из этих вариантов смысла не имеет.

ИМХО
std::auto_ptr<T const >
Лишен смысла, поскольку поскольку не имеет права сделать delete, подконтрольному объекту.

std::auto_ptr<T> const &p
опасен, поскольку компилятор имеет право создать копию std::auto_ptr<T>,
что приведет к преждевременному разрушению объекта.
Re[3]: Wilson и auto_ptr
От: Николай Ивченков  
Дата: 31.08.09 09:15
Оценка: 1 (1)
Chorkov:

C>ИМХО

C>std::auto_ptr<T const >
C>Лишен смысла, поскольку поскольку не имеет права сделать delete, подконтрольному объекту.

Почему?

C>std::auto_ptr<T> const &p

C>опасен, поскольку компилятор имеет право создать копию std::auto_ptr<T>,
C>что приведет к преждевременному разрушению объекта.

Хотелось бы увидеть конкретный пример.
Re[4]: Wilson и auto_ptr
От: Chorkov Россия  
Дата: 31.08.09 10:44
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:

НИ>Chorkov:


C>>ИМХО

C>>std::auto_ptr<T const >
C>>Лишен смысла, поскольку поскольку не имеет права сделать delete, подконтрольному объекту.
НИ>Почему?

C>>std::auto_ptr<T> const &p

C>>опасен, поскольку компилятор имеет право создать копию std::auto_ptr<T>,
C>>что приведет к преждевременному разрушению объекта.

НИ>Хотелось бы увидеть конкретный пример.


Был неправ в обоих случаях.

Полагал раз по указателю на константный объект нельзя изменить состояние объекта, то его нельзя и разрушить (сменить состояние на "разрушенный"). Типа, константных деструкторов не существует.
Однако, примечание к 5.3.5/2 меня разубедило.

Во втором случае — вообще не понимаю что на меня нашло.
Подразумевалась создание временного объекта, при "r-value to reference".

std::auto_ptr<B> new_B()
{
    return new B();
}
void f(const std::auto_ptr<B>& p)
{
 //...
}

f(new_B());
Re[5]: Wilson и auto_ptr
От: Николай Ивченков  
Дата: 31.08.09 11:41
Оценка:
Chorkov:

C>Подразумевалась создание временного объекта, при "r-value to reference".


С такой инициализацией проблема есть, но заключается она только в том, что программа может не скомпилироваться вообще. В стандарте говорится, что может быть создан дополнительный временный объект, но не говорится, какие конструкторы могут участвовать в его создании. Если конструктор auto_ptr(auto_ptr_ref<X>) не входит в set of candidate functions, то такая инициализация ill-formed; если же он входит в set of candidate functions, то он будет и viable function и тогда ошибки нет.

VC++ 8.0 с /Za, GNU C++ 4.1.2 и Comeau C++ с отключенными расширениями C++0x ругаются на такое reference binding.
Re[6]: Wilson и auto_ptr
От: igna Россия  
Дата: 01.09.09 03:53
Оценка:
Здравствуйте, Programador, Вы писали:

P>А operator* и get() почему компилируются неясно http://msdn.microsoft.com/en-us/library/b84a89af(VS.71).aspx не говорит что они константные.


А ты пойди по своей ссылке и кликни на operator* и get(), там тебе сразу и скажут.
Re[5]: Wilson и auto_ptr
От: Roman Odaisky Украина  
Дата: 02.09.09 11:17
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:

НИ>int * const f();

НИ>one &g(int const *);

НИ>считают, что f() имеет тип int * const, и выбирают вторую g


Там точно все const на своих местах?
До последнего не верил в пирамиду Лебедева.
Re[5]: Wilson и auto_ptr
От: igna Россия  
Дата: 02.09.09 12:28
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:


НИ>Причём стандарт в отношении результата вызова первой функции противоречив: с одной стороны он утверждает, что


НИ>"non-class rvalues always have cv-unqualified types" (3.10/9)


НИ>с другой — что


НИ>"The type of the function call expression is the return type of the statically chosen function" (5.2.2/3) — никакого упоминания о снятии cv-квалификации.


"Никакого упоминания" — не означает, что снятия cv-квалификации не выполняется; ее необходимость неявно следует из твоей первой цитаты.

Стандарт в этом месте туманен, но все-таки не противоречив.
Re[6]: Wilson и auto_ptr
От: Николай Ивченков  
Дата: 02.09.09 13:23
Оценка:
Roman Odaisky:

НИ>>int * const f();

НИ>>one &g(int const *);

НИ>>считают, что f() имеет тип int * const, и выбирают вторую g


RO>Там точно все const на своих местах?


Да. Впрочем, можно было и проще пример взять:

int * const f();

template <class T>
int g(T &);

int main()
{
    sizeof g(f());
}

Похоже, здесь, если убрать const в типе возврата f, VC++ своё фирменное расширение (возможность инициализации rvalue-выражением ссылки на non-const) всё равно не применяет.
Re[6]: Wilson и auto_ptr
От: Николай Ивченков  
Дата: 02.09.09 13:24
Оценка:
igna:

НИ>>"The type of the function call expression is the return type of the statically chosen function" (5.2.2/3) — никакого упоминания о снятии cv-квалификации.


I>"Никакого упоминания" — не означает, что снятия cv-квалификации не выполняется; ее необходимость неявно следует из твоей первой цитаты.


Это домыслы. Например, int и const int — это два разных типа. Если "return type of the statically chosen function" — это const int, а "type of the function call expression" — это int, то правило 5.2.2/3 в буквальной интерпретации не соблюдается — так же, как если бы в качестве "type of the function call expression" выступал бы какой-нибудь long.

I>Стандарт в этом месте туманен, но все-таки не противоречив.


Следуя 5.2.2/3 буквально, мы приходим к противоречию с 3.10/9.
Re[7]: Wilson и auto_ptr
От: igna Россия  
Дата: 02.09.09 14:21
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:

НИ>Следуя 5.2.2/3 буквально, мы приходим к противоречию с 3.10/9.


Хорошо. Ты можешь представить себе, что когда это противоречие в стандарте снимут, выиграет 5.2.2/3, а не 3.10/9? То есть, что "non-class rvalues" смогут иметь "cv-qualified types"?
Re[8]: Wilson и auto_ptr
От: Николай Ивченков  
Дата: 02.09.09 16:11
Оценка:
igna:

НИ>>Следуя 5.2.2/3 буквально, мы приходим к противоречию с 3.10/9.


I>Хорошо. Ты можешь представить себе, что когда это противоречие в стандарте снимут, выиграет 5.2.2/3, а не 3.10/9? То есть, что "non-class rvalues" смогут иметь "cv-qualified types"?


От комитета по стандартизации C++ можно ожидать чего угодно. Вот он годами работает над стандартом, а в итоге всё равно получается куча очевидных нестыковок. Как так выходит?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.