А был ли мальчик? (помянем плюсы)

User avatar
AndreyT
Уже с Приветом
Posts: 3003
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Re: А был ли мальчик? (помянем плюсы)

Post by AndreyT »

Medium-rare wrote: 23 Jan 2018 06:52 shared_ptr удовлетворяет все операции над контейнерами.
unique_ptr удовлетворяет часть операций над контейнерами.
И что?

Во-первых, львиная часть идеи шаблонного программирования как раз и заключается в том, что шаблонный класс может содержать операции, неприменимые для некоторых типов шаблонного аргумента, но это нам никак не должно мешать, пока мы не пытаемся эти операции использовать (инстанциировать).

Во-вторых, ожидание доступности всех операций контейнера - это некий С++98-стиль мышления. В С++98 первичен был сам контейнер: доминировали жесткие требования контейнера, а элемент вынужден был волей-неволей под них подстраиваться, даже если это больше нигде никому не было нужно. И это, вообще-то, плохо, ибо с точки зрения здравого смысла должно быть как раз таки наоборот - свойства элемента контейнера должны быть первичны. И они должны прозрачно проноситься (форвардиться) сквозь контейнер в окружающий мир, также как это работает с "рукописными" голыми массивами, списками и т.п.

Причем в С++98 такое жесткое доминирование правил контейнера сделали отнюдь не потому что это считалось "правильным", а просто потому, что в языке не было адекватных средств для того, чтобы сделать по-другому. Это стало возможно только в С++11. Но даже и в С++98 допустимые операции над контейнером зависели от определенных свойств элемента, хотя бы на интерфейсном уровне - например, возможность или возможность конструкции по умолчанию для элемента влияла на большое количество возможностей вызова методов контейнера.
Last edited by AndreyT on 23 Jan 2018 21:32, edited 1 time in total.
Best regards,
Андрей
User avatar
AndreyT
Уже с Приветом
Posts: 3003
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Re: А был ли мальчик? (помянем плюсы)

Post by AndreyT »

ksi wrote: 23 Jan 2018 16:47 Что все же принципиально нового есть в C++ 11, 14, ... что нельзя было сделать раньше и что значительно расширяет возможности?
Ну с такой точки зрения ничего не "расширяет возможности". Все что есть в С++ можно и всегда будет можно написать и на С, то есть тут как ни старайся, "возможностей" не "расширишь".

Тем не менее, поддержка rvalue references и move semantics - это огромное "расширение возможностей". А также есть auto, возможности делегировать конструкторы... нет смысла копипастить то, что так уже сто раз копипастено.
Best regards,
Андрей
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

M. Ridcully wrote: 22 Jan 2018 23:55
Сабина wrote: 22 Jan 2018 23:33 Ой, а дайте хороший линк где почитать про лямбды в С++ ?
А то лямбды отдельно знаю, в контексте Скалы = знаю, потом и Джавы тоже, а в контексте С++ - нет. Чувствую много пропустила :D
А чего там знать? Лямбда и в Африке - лямбда. Прочитать один раз синтаксис достаточно: http://en.cppreference.com/w/cpp/language/lambda
Вы неправы.
Не знаю как в Джаве но в C# lambda передают только по ссылке.
В С++ 11 можно по значению и по ссылке. При этом используется конструктор копирования.
В С++ 14 можно указывать как именно перемешать обьект в лямбду - copy или move конструктором.
Можно указывать модификаторы.

По мне так большая разница.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
User avatar
AndreyT
Уже с Приветом
Posts: 3003
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Re: А был ли мальчик? (помянем плюсы)

Post by AndreyT »

Сабина wrote: 22 Jan 2018 23:33 Ой, а дайте хороший линк где почитать про лямбды в С++ ?
Ну тут в первую очередь надо понимать, что лямбды в С++ - это (с небольшой натяжкой) просто syntactic sugar, надстроенный над обычными классами. Т.е. лямбда - это просто более компактный синтаксис для локального объявления некоего "безымянного" класса и локального объекта этого класса (closure object). С этой точки зрения можно сказать, что "лямбды" в С++ существовали всегда (опять же, с небольшой натяжкой). Просто раньше для создания "лямбды" надо было выписывать этот локальный класс вручную, используя обыкновенный синтаксис. А теперь то же самое просто записывается более компактно, через новый компактный shorthand синтаксис лямбда-выражения.

Материалов, описывающих эту естественную взаимосвязь, найти можно много
https://eli.thegreenplace.net/2011/11/1 ... das-in-c11

Понимание этого факта существенно облегчает понимание того, что такое лямбда в С++. Поэтому тут встает вопрос: а понимаете ли вы уже все, что нужно, для "ручной" реализации такого класса средствами "классического" С++? Если да, то бОльшая часть понимания того, что такое лямбда, у вас уже есть.
Last edited by AndreyT on 23 Jan 2018 21:09, edited 1 time in total.
Best regards,
Андрей
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

ksi wrote: 23 Jan 2018 16:47 Чем плохи обычные пойнтеры, кроме того, что надо следить за памятью? Ну и хорошо, что надо, обычно это как то дисциплинирует и заставляет продумывать дизайн. А что новое дают те же ламбды функции в отличии от С указетелей на функции по большому счету? Только что можно лениться и не передавать лишние параметры, как аргументы? Что все же принципиально нового есть в C++ 11, 14, ... что нельзя было сделать раньше и что значительно расширяет возможности? На мой вкус единственный бесспорный кандидат это vector и иже с ними. Ну невозможно работать с fixed sized array. Ну и операции со строками. Threading по прежнему примитивный, что совсем не согласуется с требованиями сегодняшнего дня.
По поводу обычных указателей ну вот навскидку:
1. В больших проектах вы за всеми указателями не уследите.
2. Код проще если есть обертка над указателем, в случае исключений хочется чтобы память освобождалась автоматически.

Лямбды
1. Эффективнее чем указатели на функцию (если не используется контекст).
2. Удобнее в использовании
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

Мальчик-Одуванчик wrote: 23 Jan 2018 02:42 auto_ptr не работает.
Без move семантики невозможно было написать правильный auto_ptr для работы с коллекциями.
Не работает потому что в коллекциях используется по умолчанию конструктор копирования вместо конструктора перемещения которого на тот момент не было.

В С++ 11 с появлением move семантики
1. По умолчанию используется конструктор перемещения
2. Eсли он не определен пользователем или нельзя применить конструктор перемещения по умолчанию то конструктор копирования или конструктор копирования по умолчанию.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

AndreyT wrote: 23 Jan 2018 02:51
Medium-rare wrote: 23 Jan 2018 01:59 Ну, shared_ptr в collections точно работает, а вот предлагаемая замена...
Одной из причин разработки unique_ptr как раз и было предоставление не-shared "умного указателя", совместимого (в отличие от auto_ptr) со стандартными контейнерами. Функциональность shared_ptr избыточна (и, поэтому, его реализация более громоздка и менее эффективна) в ситуациях, когда никакого sharing-а фактически нет.
+1
В простейшем случае когда для unique_ptr нет функции поведения при удалении то используется delete. В этом случае размер в памяти для хранения unique_ptr равно размеру для зранения обычного указателя.
Для shared_ptr используется создается память на куче для хранения счетчика и указателя на функцию удаления.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
User avatar
AndreyT
Уже с Приветом
Posts: 3003
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Re: А был ли мальчик? (помянем плюсы)

Post by AndreyT »

Pantigalt wrote: 23 Jan 2018 21:13 В С++ 11 с появлением move семантики
1. По умолчанию используется конструктор перемещения
2. Eсли он не определен пользователем или нельзя применить конструктор перемещения по умолчанию то конструктор копирования или конструктор копирования по умолчанию.
Вообще-то "симуляция" move semantics в `std::auto_ptr` через `std::auto_ptr::auto_ptr_ref` была достаточной for all means and purposes (хоть местами и опасной). Проблема была в том, что move semantics не принималась во внимание в разработке остальных частей стандартной библиотеки. То есть реализации контейнеров, алгоритмов и т.п. имели право рассчитывать на эквивалентность копирования и требовать этой эквивалентности. Начиная с С++11 move semantics начали принимать во внимание и контейнеры с алгоритмами стали реализовывать более аккуратно.

То есть проблема была не столько в `std::auto_ptr`, сколько в том, что его суррогатную реализацию move semantics не принимали всерьез.
Best regards,
Андрей
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

AndreyT wrote: 23 Jan 2018 20:24
ksi wrote: 23 Jan 2018 16:47 Что все же принципиально нового есть в C++ 11, 14, ... что нельзя было сделать раньше и что значительно расширяет возможности?
Ну с такой точки зрения ничего не "расширяет возможности". Все что есть в С++ можно и всегда будет можно написать и на С, то есть тут как ни старайся, "возможностей" не "расширишь".

Тем не менее, поддержка rvalue references и move semantics - это огромное "расширение возможностей". А также есть auto, возможности делегировать конструкторы... нет смысла копипастить то, что так уже сто раз копипастено.
ksi
Раньше стандартные контейнеры надо было копировать. Теперь их можно перемещать если оригинальный объект уже не нужен.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

AndreyT wrote: 23 Jan 2018 21:29
Pantigalt wrote: 23 Jan 2018 21:13 В С++ 11 с появлением move семантики
1. По умолчанию используется конструктор перемещения
2. Eсли он не определен пользователем или нельзя применить конструктор перемещения по умолчанию то конструктор копирования или конструктор копирования по умолчанию.
Вообще-то "симуляция" move semantics в `std::auto_ptr` через `std::auto_ptr::auto_ptr_ref` была достаточной for all means and purposes (хоть местами и опасной). Проблема была в том, что move semantics не принималась во внимание в разработке остальных частей стандартной библиотеки. То есть реализации контейнеров, алгоритмов и т.п. имели право рассчитывать на эквивалентность копирования и требовать этой эквивалентности. Начиная с С++11 move semantics начали принимать во внимание и контейнеры с алгоритмами стали реализовывать более аккуратно.

То есть проблема была не столько в `std::auto_ptr`, сколько в том, что его суррогатную реализацию move semantics не принимали всерьез.
Я читал что ее намеренно сделали несовместимой со стандартными контейнерами с прицелом на то что изменят это в будущем.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
User avatar
Medium-rare
Уже с Приветом
Posts: 9195
Joined: 04 Mar 2011 03:04
Location: SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Medium-rare »

Pantigalt wrote: 23 Jan 2018 21:26 Для shared_ptr используется создается память на куче для хранения счетчика и указателя на функцию удаления.
Medium-rare wrote: 23 Jan 2018 03:38 Не то, чтобы я призывал то или другое использовать в котейнерах.
Medium-rare wrote: 23 Jan 2018 17:55 Чтобы не плодить сущности в случае с контейнером, начиная с C++ 11 moveable тип ему давать.
И жить долго, и счастливо, не зная про требования сегодняшнего дня.
Посмотреть на вещи с практической стороны, и не заболтать.
... and even then it's rare that you'll be going there...
User avatar
M. Ridcully
Уже с Приветом
Posts: 12017
Joined: 08 Sep 2006 20:07
Location: Силиконка

Re: А был ли мальчик? (помянем плюсы)

Post by M. Ridcully »

Pantigalt wrote: 23 Jan 2018 21:26
AndreyT wrote: 23 Jan 2018 02:51
Medium-rare wrote: 23 Jan 2018 01:59 Ну, shared_ptr в collections точно работает, а вот предлагаемая замена...
Одной из причин разработки unique_ptr как раз и было предоставление не-shared "умного указателя", совместимого (в отличие от auto_ptr) со стандартными контейнерами. Функциональность shared_ptr избыточна (и, поэтому, его реализация более громоздка и менее эффективна) в ситуациях, когда никакого sharing-а фактически нет.
+1
Я, кстати, до сих пор не понимаю глубоко (ну необходимости просто нет) что такое эти самые move semantics & rvalue references.

Придумал для себя упрощенную картину мира - "это магия, с помощью которой работает unique_ptr". Меня это собственное объяснения пока устраивает. :D
Мир Украине. Свободу России.
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

Medium-rare wrote: 23 Jan 2018 23:28
Pantigalt wrote: 23 Jan 2018 21:26 Для shared_ptr используется создается память на куче для хранения счетчика и указателя на функцию удаления.
Medium-rare wrote: 23 Jan 2018 03:38 Не то, чтобы я призывал то или другое использовать в котейнерах.
Medium-rare wrote: 23 Jan 2018 17:55 Чтобы не плодить сущности в случае с контейнером, начиная с C++ 11 moveable тип ему давать.
И жить долго, и счастливо, не зная про требования сегодняшнего дня.
Посмотреть на вещи с практической стороны, и не заболтать.
Не уверен что я понял что вы хотите сказать.
Вы предлагаете упростить язык и помечать классы модификатором moveable?
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
User avatar
Medium-rare
Уже с Приветом
Posts: 9195
Joined: 04 Mar 2011 03:04
Location: SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Medium-rare »

Ни тот, ни другой smart pointer не бьют тип с прописанным move, помещённый в контейнер. Это если давить на то, что хорошо.
Полная операбльность, и без потерь в чём-либо. А тут как везде в Интернете, мы себе представляем не совсем то, что говорится.

Дайте контейнерному типу move semantics. Ну, для примера.
... and even then it's rare that you'll be going there...
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

Medium-rare wrote: 24 Jan 2018 00:32 Ни тот, ни другой smart pointer не бьют тип с прописанным move, помещённый в контейнер. Это если давить на то, что хорошо.
Полная операбльность, и без потерь в чём-либо. А тут как везде в Интернете, мы себе представляем не совсем то, что говорится.

Дайте контейнерному типу move semantics. Ну, для примера.
Про moveable тип Вы правы.
Ну я и не настаивал на том что надо обязательно использовать умные указатели в контейнерах вместо самих объектов.
Непонятно о чем мы спорим тогда.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко

Return to “Вопросы и новости IT”