Лекция 1. Нововведения стандарта C++11

  Рет қаралды 31,898

PVS-Studio Ru

PVS-Studio Ru

Күн бұрын

Пікірлер: 60
@evgenytoropov8134
@evgenytoropov8134 5 жыл бұрын
Отличная лекция. Посмотрел и еще потом пересмотрю
@Andyy538
@Andyy538 5 жыл бұрын
Спасибо, что делитесь! Интересно послушать настоящих практиков о их понимании С++.
@Avenir-Sigrun
@Avenir-Sigrun Жыл бұрын
огромное пасибо, Филипп.👍
@alex_nevskiy_888
@alex_nevskiy_888 4 жыл бұрын
Довольно качественная лекция, и качественно сделанный для понимания ролик.
@ozimandias1738
@ozimandias1738 Жыл бұрын
Офигенные лекции. Совершенно случайно нашел, гуглив метапрограммирование)
@kpanat
@kpanat Жыл бұрын
С перемещениями могут быть проблемы...например вы пишете такой код: { constexpr size_t SZ = 100; int arr[SZ]; FillArray(1, 500, arr, SZ, true); Vector vec(arr, SZ); } Во второй строке массив заполняется что не играет роли. Ошибка в 4-ой строке. У шаблона Vector есть конструктор перемещения. Он берёт и указатель на int взаимствует присваивая ему nullptr как обычно это делается. А когда код выходит из области видимости вектора разумеется вызывается деструктор который освобождает память. и тут возникает исключение потому что память эта не из динамической памяти а из статической и по сути на стеке если нее глобальная. Это было бы если бы мы вынесли определение arr туда. Просто ошибка происходила бы при закрытии программы. Как исправить? Во первых у Vector дб ещё и обычный конструктор с копированием и таким же списком. Но в качестве аргумента надо написать не Vector(T *&&ar, const size_t sz) а Vector(соnst T *ar, const size_t sz) и если будет вызван 2-ой конструктор, то проблем не будет. Но создаст динамическую память в неё запишет значения а потом в деструкторе её освободит. внешне вызов выглядит одинаково они не различимы. и компилятор будет стабильно вызывать конструктор перемещения, а должен вызывать конструктор копирования. Из lvalue можно сделать rvalue, а вот наоборот нельзя!!! потому что у rvalue нет адреса... По крайнй мере при вызове. Но если преобразовать arr в константный указатель это заставит компилятор вызвать именно конструктор с копированием, а не перемещением. И проблема будет решена. А как по другому я не знаю...
@proalex111
@proalex111 3 жыл бұрын
Спасибо, человечище!
@KIR_Engineer
@KIR_Engineer 3 жыл бұрын
Топовая лекция! Спасибо!
@Scherbakov
@Scherbakov 3 жыл бұрын
Спасибо! Отличная лекция!
@user-wu3vd7dd2r
@user-wu3vd7dd2r 4 жыл бұрын
огромное пасибо, Филипп. клевая лекция
@RomanTrufanov
@RomanTrufanov 4 жыл бұрын
Спасибо! Это круто!
@5111
@5111 3 жыл бұрын
топовый чел
@sashabroslavskiy7904
@sashabroslavskiy7904 2 жыл бұрын
Божественно.
@Эрдан-з5ч
@Эрдан-з5ч 2 жыл бұрын
круто 👍
@АлексейПлотник
@АлексейПлотник 5 жыл бұрын
Больше всего понравилось то, что спикер похож на Тесака. Доклад тоже хороший.
@riz1_k
@riz1_k Жыл бұрын
Я не один кто также подумал XD
@socketam4524
@socketam4524 5 жыл бұрын
Хорошие лекции, спасиб. Единственная просьба - хватит проталкивать)
@kpanat
@kpanat Жыл бұрын
я имею ввиду rfor. Нет не по любой коллекции, по массиву нельзя если в данном месте компилятор не знает его размера. Например при передаче его в функцию через указатель. Так же по динамическому массиву нельзя... Но если написать например int *arr[]{1, 2, 3, 10, -5};(в с++20 так можно) то rfor работает. Потому что тут компилятор знает его размер на этапе компиляции. И да, этот указатель можно мувить в отличие от указателя на статическую память. Хорошо ведь правда? Вот...
@theK0sh
@theK0sh 5 жыл бұрын
Для примера на 16:24 разве не достаточно вынести создание объекта std::pair за цикл, а в цикле уже присваивать второй паре значение i и этот объект дальше передавать в вектор. Наивная, но эффективная оптимизация..
@PVSStudioTool
@PVSStudioTool 5 жыл бұрын
В целом, да, для этого примера такую оптимизацию можно сделать. При этом на каждой итерации будет вызываться конструктор копирования std::pair, что вызовет конструктор копирования MyString. Однако цимес данного примера в том, что до C++11 если в функцию передавали временный объект как фактический аргумент, а формальный аргумент являлся ссылкой на константу, то компилятор с этим не мог ничего поделать, и производил копирование временного объекта, что "дорого". Собственно, этот хитрый "бенчмарк" для этого и предназначен (на самом деле надо было в примере передавать не одну и ту же строку в конструктор пары). Проблема была очень насущной, и приходилось использовать разные ухищрения для устранения ненужного копирования, например COW (Copy on Write) - в строчку добавляли счетчик ссылок, и при копировании строки производилось его увеличение, в деструкторе - уменьшение. Если строчку каким-либо образом меняли, то создавался новый экземпляр строки, счетчик для новой строки приравнивался единице. Как счетчик ссылок равнялся нулю - динамически аллоцированную строчку прибивали.
@RedJerick
@RedJerick 5 жыл бұрын
На 58:00 непонятно, разве компилятор не должен сгенерировать за нас конструкторы и операторы присваивания по умолчанию, то есть мы просто можем опустить объявление этих конструкторов? И зачем тогда default...
@Playerzed
@Playerzed 5 жыл бұрын
Если определить какой-нибудь конструктор вручную, то конструктор по умолчанию, простите за тавтологию, не генерируется по умолчанию. Чтобы указать что его все равно нужно сгенерировать, нужен будет default.
@nocs13
@nocs13 5 жыл бұрын
А не странно то что ядро большенство перечистлених программ написан на чистом C. почему все написанное на С пречистлается к С++... не честно же... протесту...
@Dmitriy12397
@Dmitriy12397 3 жыл бұрын
57:32 опечатки в коде?
@Simo_IT_channel
@Simo_IT_channel Жыл бұрын
PVS studio объясните пожалуйста вот такой момент, про создании лямбды и указании ввиде списка захвата & как именно будет формироваться класс на уровне компилятора, тоесть как он в поля запихнет все что есть снаружи?
@PVSStudioTool
@PVSStudioTool Жыл бұрын
kzbin.info/www/bejne/jHaWmKJtpsh6ZpYsi=zd7HzYkWv_BeupdA&t=2023 Вы опередили своим вопросом нас)
@КонстантинКочев-ш4э
@КонстантинКочев-ш4э 4 жыл бұрын
Почему в С++ отказались от инициализации полей структур по именам полей? В простом С очень удобно. Т.е. struct rect textRect = { .Left = 0, .Top = 0, .Width = 320, .Height = 100 } в простом C возможно, а в плюсах нет.
@PVSStudioTool
@PVSStudioTool 4 жыл бұрын
В C++20 таки подвезли: en.cppreference.com/w/cpp/language/aggregate_initialization#Designated_initializers Однако есть небольшое ограничение в отличие от языка C - инициализаторы полей должны идти в том же порядке, в котором объявлены поля. Почему именно так? Ответ прост - конструкторы: то, в каком порядке создаются поля классов, отличается в этих языках. Подробнее здесь - en.cppreference.com/w/cpp/language/initializer_list#Initialization_order.
@MrTruth2
@MrTruth2 3 ай бұрын
Разве Яндекс браузер не тот же хром ?
@kirchann
@kirchann 4 жыл бұрын
48:45. У меня не удалось воспроизвести проблему :(
@PVSStudioTool
@PVSStudioTool 4 жыл бұрын
Давайте разбираться в этом. Нас интересует вот этот пункт стандарта: eel.is/c++draft/class.temporary#6.4 Если вкратце, то если мы захватываем ссылку на поле временного объекта, доставая его через оператор "точка", то ссылка продлевает время жизни как временного объекта, так и вектора, поэтому все хорошо. godbolt.org/z/NSz6s7 Но если мы захватываем ссылку, которая возвращает функция (ссылка на поле класса), то тут уже "ква" - ловим Undefined Behavior. godbolt.org/z/QHzmoj Спасибо, что заметили, в лекциях поправим это место :)
@earthnews7724
@earthnews7724 Жыл бұрын
Спасибо за лекции, но я понял 5% )))
@PVSStudioTool
@PVSStudioTool Жыл бұрын
5% это хорошее начало )
@Dmi3S
@Dmi3S 5 жыл бұрын
Формально среди умных указателей есть еще и std::exception_ptr.
@АннаКонева-ц4с
@АннаКонева-ц4с 3 жыл бұрын
А можно написать, как называется проблема со скобками - most что-то там...? Не расслышала...
@PVSStudioTool
@PVSStudioTool 3 жыл бұрын
Не подскажите таймкод? :)
@СергейСергей-ч3ч6й
@СергейСергей-ч3ч6й 3 жыл бұрын
Полностью не смотрел, но может most vexing parse?
@uss3ewa
@uss3ewa 2 жыл бұрын
1:40:05 а можно уточнить про что это?
@PVSStudioTool
@PVSStudioTool 2 жыл бұрын
Речь идёт о spaceship operator (en.cppreference.com/w/cpp/language/default_comparisons#Defaulted_three-way_comparison). Более подробно останавливались на нём в лекции 12 (kzbin.info/www/bejne/gYHYiqGVm7qXrsU&ab_channel=PVS-StudioRu). Если коротко - теперь можно написать следующий код: struct SomeStruct { int n; std::string s; float d; auto operator(const SomeStruct &) const = default; }; А всё :) Теперь компилятор сможет за вас сгенерировать тела всех операторов сравнения. Кода стало заметно меньше. Если требуется более сложная кастомная логика - просто пишем свою имплементацию.
@sergeyvlasov207
@sergeyvlasov207 2 жыл бұрын
49:37 std::greater ?
@PVSStudioTool
@PVSStudioTool 2 жыл бұрын
Да, в том примере для сортировки по убыванию действительно можно воспользоваться функциональным объектом "std::greater", даже до C++11. Однако если потребуется более сложная логика, до C++11 пришлось бы реализовывать кастомный класс с перегруженным "operator()". Скорее всего, вы бы не хотели, чтобы этот класс был виден снаружи вашей функции, т.е. класс бы пришлось делать локальным. C++11 добавил анонимные функции, которые делают все то же самое за вас. Если копнуть еще глубже, то лямбды имеют преимущество над локальными классами. Например, у последних имеется вот такой список ограничений (en.cppreference.com/w/cpp/language/class#Local_classes). Наиболее существенный из них - невозможность определять внутри класса шаблоны. Обобщенные лямбды из C++14 не имеют такого недостатка, и можно смело использовать (godbolt.org/z/rfbErEYxE) ключевое слово "auto" при объявлении формальных параметров. Объявление хотя бы одного такого формального параметра делает перегруженный оператор внутри лямбды шаблоном.
@sergeyvlasov207
@sergeyvlasov207 2 жыл бұрын
@@PVSStudioTool Спасибо что потратили время и дали очень развернутый ответ :)
@PVSStudioTool
@PVSStudioTool 2 жыл бұрын
@@sergeyvlasov207 Спасибо, что смотрите наши видео)
@vladimirmedvedev9222
@vladimirmedvedev9222 5 жыл бұрын
Стандарт плюсов неисчерпаем, матчасть учите, кто не глуп - и будет вам тогда и страус, и труп.
@byte_machine
@byte_machine 3 жыл бұрын
Его пример другим наука, Когда он начал прозревать, Стандарт открыл, чертей всех вспомнил, И мать.
@vadimkozub3400
@vadimkozub3400 Жыл бұрын
лайк
@kpanat
@kpanat Жыл бұрын
Ну мы же понимаем, что выражение TimeKeeper time_keeper(Timer()); не есть определение функции которая возвращает TimeKeeper и принимает на входе другую функцию возвращающую Timer и не принимающую никаких аргументов. Т.е. по сути Timer(*fun)() или TimeKeeper time_keeper(Timer(*fun)()) для пущей убедительности. Вот щаз она точно выглядит как декларация функции с именем time_keeper. Но у этой функции нет метода get_time. У функции я должен сказать вообще нет никаких методов в отличие от TimeKeeper у которого такой метод есть. Вот на это компилятор и ругается. Чего вы там совсем ку-ку вызываете метод у функции? К слову сказать у функционального объекта могут быть методы и поля, а у просто функции нет... Но мы-то вовсе не это хотели написать а определение экземпляра класса TimeKeeper с инициаллизацией которая описана в его конструкторе. Но как это объяснить компилятору если у него в приоритете функциональный подход а потом классовый. Хотя тов Ленин учил, что ко всему нужен классовый подход. И если бы компилятор так сделал как учил наш великий учитель тов Ленин то компилятор бы не запутался в 3-х соснах а сделал бы всё правильно... А не решил что это какая-то непонятная ХРЕНЬ и потом начал на эту ХРЕНЬ ругаться, которой там даже не предполагалось. О как! Ну не всё хорошо делает компилятор, но они над этим работают и пытаются устранить... Пока 23-ая версия пошла. Модули я ещё не пробовал. Но на паскале писал когда-то... Там всё примерно так как сказано в описании. Впрочем я это сразу заметил. на Фортране тоже модули.. И на Питоне с перлом. И только на плюсах хэдера. В связи с этим вопрос, а как dll писать? Ведь там это принципиально важно. И не только там... Если нет хэдеров то как же тогда? Или сделают ещё один формат выполняемых, подключаемых файлов? В паскале это TPU блин... 1994 год глубокое средневековье, а там модули!!! Я всегда говорил, что всё новое это просто хорошо забытое старое. Мы ходим по кругу... Ничего принципиально нового не выдаём... Всё где-то когда-то как-то было.
@PVSStudioTool
@PVSStudioTool Жыл бұрын
Ну мы же понимаем, что выражение TimeKeeper time_keeper(Timer()); не есть определение функции которая возвращает TimeKeeper и принимает на входе другую функцию возвращающую Timer и не принимающую никаких аргументов. Это человек понимает семантически, что здесь декларируется объект, потому что это было его желание. А вот стандарт C++, по которому реализованы компиляторы, здесь не согласен. И дело в тяжком наследии C. C++ исторически создавался как расширение C, поэтому грамматика была переиспользована. И к сожалению, по стандарту здесь предпочитается грамматическое правило по разбору декларации функции, поскольку не встретилось ничего, что могло бы остановить парсинг согласно этому правилу. Вы можете попробовать изменить это, отправив предложение в стандарт: stdcpp.ru/proposals Но успеха здесь ждать не стоит. Ведь C++ развивается с ориентацией на обратную совместимость с языком C. Только создавать другой диалект C++, как например этим занимается Герб Саттер (C++2): github.com/hsutter/cppfront
@PVSStudioTool
@PVSStudioTool Жыл бұрын
В связи с этим вопрос, а как dll писать? Примерно так же, как и раньше :) Итоговое приложение или динамическая библиотека получается после линкера. Здесь ничего не поменяли. Изменили этап компиляции с применением модулей. Модуль состоит из интерфейсного файла и имплементации. Когда модуль компилируется, компилятор формирует 2 файла: обычный объектный файл для линковки и BMI (Binary Module Interface). Первый всё также передается линкеру, а вот второй использует компилятор, когда встречает import в компилируемом файле. Т.к. модуль не меняется из-за внешних макроопределений (в отличие от заголовочных файлов), это позволяет сериализовать некоторое промежуточное представление в BMI и десериализовывать его, не тратя время на повторный разбор кода.
@AlexSmile-y2x
@AlexSmile-y2x 10 ай бұрын
JVM на С пишется а не на С++, жеж))
@РайанКупер-э4о
@РайанКупер-э4о 3 жыл бұрын
Стой, а до 11го лямбд не было?
@PVSStudioTool
@PVSStudioTool 3 жыл бұрын
Были функциональные объекты (предикаты), но это всё нужно было делать руками... Только с 11-тых пришли нормальные лямбды (((
@int32h60
@int32h60 3 жыл бұрын
откуда он знает что было изменено в 20 стандарте, если видео выпущено 1 окт 2019, а c++20 в декабре 2020?
@creepymuffin2351
@creepymuffin2351 3 жыл бұрын
Я так понимаю все благодаря boost библиотекам, либо благодаря ранним официальным анонсам || инсайдерской инфе. Что-то вроде того, когда все за полгода до выхода уже знают дизайн следующего айфона)
@xbevice
@xbevice 4 жыл бұрын
90% из всего перечисленного писано на С без плюсов.
@Blow_BacK
@Blow_BacK Жыл бұрын
вроде на си писать умею, но из того что говорит этот дядька не имеет смысла ничего. насколько же я тупой((
@PVSStudioTool
@PVSStudioTool Жыл бұрын
Вовсе нет, но теперь вы стали чуть более образованным)
Лекция 2. Нововведения стандарта C++14
37:04
Mom Hack for Cooking Solo with a Little One! 🍳👶
00:15
5-Minute Crafts HOUSE
Рет қаралды 20 МЛН
Quando A Diferença De Altura É Muito Grande 😲😂
00:12
Mari Maria
Рет қаралды 36 МЛН
Лекция 3. Вывод типов в C++
53:36
PVS-Studio Ru
Рет қаралды 6 М.
Лекция 4. Нововведения стандарта С++17
1:35:23
Алгоритмы и структуры данных (С++), лекция №1
1:26:53
Тимофей Хирьянов
Рет қаралды 536 М.
Задача из Собеседования на 160,000 Евро в Год
13:27
Саша Лукин
Рет қаралды 1,1 МЛН
Введение в язык программирования Go
1:36:18
Computer Science Center
Рет қаралды 90 М.
Review Máy Đếm Tiền Tính Tổng #shorts
0:26
Review Máy Đếm Tiền
Рет қаралды 21 МЛН
Introducing the "VitaWear SmartBand," a next-generation wearable gadget🎉
0:48
Vrashika Rajput Official
Рет қаралды 33 МЛН
Máy báo tín hiệu bảo vệ trẻ nhỏ
0:34
SaboMall
Рет қаралды 1,6 МЛН
Mac Mini M4 - ОН ИЗМЕНИТ ИГРУ
17:47
ЗЕ МАККЕРС
Рет қаралды 48 М.
Máy báo tín hiệu bảo vệ trẻ nhỏ
0:34
SaboMall
Рет қаралды 1,6 МЛН