@ а можно ссылочки, даже интересно, где реализуют таким образом вполне конкретную noexcept функцию, возвращающую по стандарту static_cast?.. хочу пополнить свой багаж знаний
@@КириллЧе-я5ы, исходный код STL открыт. Можешь посмотреть реализацию STL в Visual Studio, если у тебя она есть, если нету, то реализация STL от GCC лежит на гитхабе (только у каждого реализация своя)
Я их называю «временные ссылки». Злой шаблонщиной решить можно, но уровень языка хорош тем, что это может перемещать там, где раньше неявно копировалось (параметры, return), а также автоматически применять это для временных объектов. Да, рассказывая про forward, я говорю: снаружи функция требует временную ссылку. Но внутри (для безопасности - любая потеря данных хуже любой неоптимальности) параметр именованный, и потому std::move. По той же причине - выведением типов нельзя отличить T& от T&& - std::forward требует параметр. И ещё говорю, что move лишь говорит: «этот объект именованный, но, поверьте, его можно потрошить». Реальным потрошением занимается конструктор перемещения. Или любая другая функция с временной ссылкой.
Обожаю плюсы! Всегда найдётся способ выстрелить себе в ногу. =) Хотелось бы, чтобы автор также упомянул о том, что компилятор может предоставлять конструктор и оператор перемещения по умолчанию при определённых условиях. Надеюсь, в будущих видео будут раскрыты юз-кейсы использования семантики перемещения и различные её нюансы. Например, особенности при использовании с виртуальными классами, когда мы перемещаем объект производного класса через объект базового класса. Если не секрет, какая IDE используется в видео? Спасибо за видео, однозначно лайк!
На самом деле, можно, частино, решить проблему перемещения, обходясь исключительно l-value ссылками, не "убивая" семантику копирования. Как верно заметили, семантика перемещения включает в себя как минимум перегрузку конструктора и оператора присваивания. Т.е. мы можем создать любой другой конструктор, так, чтобы он отличался от конструктора копирования. Например, можно ввести новый класс, который в себе хранит ссылку на источник перемещения, и, примем как соглашение, что данный адаптер нужно использовать, когда необходимо переместить объект: template struct Movable { T& movable; }; Тогда можно сделать следующий конструктор class Example { public: Example(Example const&); // copy ctor Example(Movable&); // move-like ctor }; Далее уже можно развить эту тему для более удобного использования, но, как я уже говорил, это может лишь частично решить проблему, так как будет не доступна возможность создавать временный обект, который передается сразу как аргумент. Т.е. без полноценной поддержки новых типов ссылок нельзя было бы корректно написать что-то вроде: Example e(std::move(Example())); Причина в том, что время жизни такого временного объекта можно продлить только через l-value ссылку на константу, а перемещение требует чтобы ссылка была как раз таки не константная. Возможно кому-то может показаться что в таком случае можно применить снятие константности через const_cast, но это уже прямо таки конкретный костыль, который может привести к UB, и, лично я думаю, что именно эта причина была одна из основных в мотивации добавить именно новый вид ссылок для поддержки семантики перемещения.
Я все еще сижу на с++99 и счастлив. И стал еще счастливее со времен бурных изменений языка, превративших его в какую-то клинопись, да еще и зашифрованную.
Про NRVO и RVO надо бы упомянуть. Из-за гарантированного NRVO при возврате по значению, надо положить результат во временную переменную и возвращать еë. Вопрос по контейнерам STL. Если у объекта - элемента контейнера move конструктор (или move assignment operator) обьявлен не noexcept, то будет использован copy конструктор (оператор)? Если да, то каким образом определяется, что нет объявления noexcept?
Простите, я не сишник. А чем вызвано острое желание держать объекты в стеке? Можно без головной боли работать с указателями, и тогда никакие копирующие конструкторы в принципе не вызываются - копируется сам указатель.
Термин "вектор" ввели всего 2 человека без каких-либо на то научных оснований. Его нужно вообще убрать из программирования за исключением математических векторов.
Вот такого блогера нам не хватало.
бро, продолжай снимать дальше! это самый качественный контент по плюсам во всем снг
Самое главное в семантике перемещения это то, что std::move ничего не перемещает!
Если ты про то, что std::move обёртка над memmove, то да
@@R3v0ultвообще-то это обёртка над статик каст как правило…
@@КириллЧе-я5ы, да, но у него 3 перегрузки и только 1 из них это статик каст
@ а можно ссылочки, даже интересно, где реализуют таким образом вполне конкретную noexcept функцию, возвращающую по стандарту static_cast?.. хочу пополнить свой багаж знаний
@@КириллЧе-я5ы, исходный код STL открыт. Можешь посмотреть реализацию STL в Visual Studio, если у тебя она есть, если нету, то реализация STL от GCC лежит на гитхабе (только у каждого реализация своя)
Лайк автору за его разборы. Добовляет понимание, над чем и с чем придётся работать. Предоставляет понимание в программировании.
Классный канал. Спасибо тебе!
Друг, огромное спасибо за видео!
Ооо. Новое видео. Круто. Очень полезно. Спасибо большое
Я их называю «временные ссылки». Злой шаблонщиной решить можно, но уровень языка хорош тем, что это может перемещать там, где раньше неявно копировалось (параметры, return), а также автоматически применять это для временных объектов.
Да, рассказывая про forward, я говорю: снаружи функция требует временную ссылку. Но внутри (для безопасности - любая потеря данных хуже любой неоптимальности) параметр именованный, и потому std::move. По той же причине - выведением типов нельзя отличить T& от T&& - std::forward требует параметр.
И ещё говорю, что move лишь говорит: «этот объект именованный, но, поверьте, его можно потрошить». Реальным потрошением занимается конструктор перемещения. Или любая другая функция с временной ссылкой.
Обожаю плюсы! Всегда найдётся способ выстрелить себе в ногу. =)
Хотелось бы, чтобы автор также упомянул о том, что компилятор может предоставлять конструктор и оператор перемещения по умолчанию при определённых условиях.
Надеюсь, в будущих видео будут раскрыты юз-кейсы использования семантики перемещения и различные её нюансы. Например, особенности при использовании с виртуальными классами, когда мы перемещаем объект производного класса через объект базового класса.
Если не секрет, какая IDE используется в видео?
Спасибо за видео, однозначно лайк!
QtCreator
На самом деле, можно, частино, решить проблему перемещения, обходясь исключительно l-value ссылками, не "убивая" семантику копирования. Как верно заметили, семантика перемещения включает в себя как минимум перегрузку конструктора и оператора присваивания. Т.е. мы можем создать любой другой конструктор, так, чтобы он отличался от конструктора копирования. Например, можно ввести новый класс, который в себе хранит ссылку на источник перемещения, и, примем как соглашение, что данный адаптер нужно использовать, когда необходимо переместить объект:
template
struct Movable {
T& movable;
};
Тогда можно сделать следующий конструктор
class Example {
public:
Example(Example const&); // copy ctor
Example(Movable&); // move-like ctor
};
Далее уже можно развить эту тему для более удобного использования, но, как я уже говорил, это может лишь частично решить проблему, так как будет не доступна возможность создавать временный обект, который передается сразу как аргумент. Т.е. без полноценной поддержки новых типов ссылок нельзя было бы корректно написать что-то вроде: Example e(std::move(Example()));
Причина в том, что время жизни такого временного объекта можно продлить только через l-value ссылку на константу, а перемещение требует чтобы ссылка была как раз таки не константная. Возможно кому-то может показаться что в таком случае можно применить снятие константности через const_cast, но это уже прямо таки конкретный костыль, который может привести к UB, и, лично я думаю, что именно эта причина была одна из основных в мотивации добавить именно новый вид ссылок для поддержки семантики перемещения.
Блин когда давно это знаешь, но кто то другой объясняет, то немного по-другому начинаешь понимать. Чаще это использовать буду.
Ого! А я думал канал загнулся... Its alive!🎉
Еще до std::move в примерах из видео, при инициализации срабатывала бы такая штука, copy elision. Тоже та еще хрень неочевидная…
Я все еще сижу на с++99 и счастлив. И стал еще счастливее со времен бурных изменений языка, превративших его в какую-то клинопись, да еще и зашифрованную.
Что ты пишешь? Где работаешь?
Если у вас такие большие объекты это либо одноразовая акция для инициализации или у вас что-то не так
Про NRVO и RVO надо бы упомянуть. Из-за гарантированного NRVO при возврате по значению, надо положить результат во временную переменную и возвращать еë.
Вопрос по контейнерам STL. Если у объекта - элемента контейнера move конструктор (или move assignment operator) обьявлен не noexcept, то будет использован copy конструктор (оператор)? Если да, то каким образом определяется, что нет объявления noexcept?
Ты ещё про declval и launder расскажи))) Тогда у кого-то протечёт)))
Я воще не вижу проблемы в том что выделять дважды память я вижу проблему в неразумно больших классах.
Простите, я не сишник. А чем вызвано острое желание держать объекты в стеке? Можно без головной боли работать с указателями, и тогда никакие копирующие конструкторы в принципе не вызываются - копируется сам указатель.
С памятью на стеке работа осуществляется быстрее
@@arekusei9580 Это из за исключений, чтобы не потерять память. Исключения идут по стеку и освобождают выделенную память (RAII).
Звук отстает
нормальные люди смотрят на фоне)
Термин "вектор" ввели всего 2 человека без каких-либо на то научных оснований. Его нужно вообще убрать из программирования за исключением математических векторов.
вроде ж после std17 это уже не нужОное?
Какая же гадость этот ваш цпп
Это полный абзац.
Убери здоровенный микрофон в другое место плиз
- А куда его засунуть-то?
- Поручик, молчать!!!