LINUX.ORG.RU

С++23 уже почти здесь

 


3

4

по мотивам прошлой темы: Вести с полей стандартизации C++: C++20 design is complete (Kona, 2019-02)

Появился пост на reddit в котором можно увидеть какие ещё предложения войдут в С++23, возможно войдут в С++23, и не войдут: https://old.reddit.com/r/cpp/comments/qug17i/c23_near_the_finish_line/

Также можно увидеть что уже вошло в С++23 https://en.cppreference.com/w/cpp/compiler_support/23

Жалко, что

P1673 (P1385)	A free function linear algebra interface based on the BLAS	[9] NO
P1385 (P1673)	A proposal to add linear algebra support to the C++ standard library   [9] NO

Но тем не менее получилось не мало.

Кстати, если у вас есть негативный опыт с ranges_v3 и Boost.Range, то std::ranges гораздо более оптимизирован к скорости компиляции:

https://www.reddit.com/r/cpp/comments/qug17i/c23_near_the_finish_line/hkw97si/

★★★★★

Последнее исправление: fsb4000 (всего исправлений: 2)

Ответ на: комментарий от anonymous

Ещё одна жертва пропаганды. Никакого C++ модули ненужны и модули в С++ совершенно не то, что модули в скриптухах. Изучи тему и не позорься.

nonedi18
()
Ответ на: комментарий от eao197

Кто виноват в том, что ты не можешь писать код? Да ладно не можешь - ты даже о pm ничего не знаешь.

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

А ну и заход уровня «мне не нравится порядок аргументов». Я понимаю, что тебе сложно, но попытайся спастить враппер там, где спастил overloadded. Он пишется в две строки.

nonedi18
()
Ответ на: комментарий от eao197

С std::variant все просто – количество вариантов жестко ограничено и известно во время компиляции. Поэтому компилятор может проверить полноту матчинга (практически так, как это сейчас происходит при использовании std::visit)

Да-да, я уже вижу причину недопонимания. Ты предполагаешь, что std::variant будет хранить банальное <bool, int, double>, я же скорее имел в виду какое-нибудь дерево JSON с

typedef std::shared_ptr<std::variant<Bool, Number, String, Array, Map> > Value;
typedef std::shared_ptr<std::vector<Value> > Array;
и так далее, я предпочту опустить здесь описание ассоциативных массивов и решение вопроса ссылки на родительский узел. Соответственно, разгребать эту гору контейнеров примитивными инструментами, на которые ты намекаешь, будет очень грустно, и даже банальная функция «по строке-ключу получить строку-значение» выйдет при таких раскладах на экран кода с корректной обработкой всех типов и пустых значений. А вот потому что либо экран кода, либо неточный/неполный матчинг. И особенно подливает масла в огонь ублюдочная система cv-модификаторов, из-за которых vector<const T&> и vector<T&> являются двумя несовместимыми контейнерами. Такие замечательные преимущества проверки полноты матчинга никому не уперлись, потому вся индустрия пишет на JS и питоне, и даже в C++ оно почти никому не нужно.

byko3y ★★★★
()
Ответ на: комментарий от eao197

Можно обойтись. Только вот стоить (в человекочасах) это будет сильно дороже. По моему опыту, в разы

Я твоего опыта не знаю, так что извиняй.

Как раз последние 2 недели писал код, который под Windows использует overlappedIO. И C++ные возможности по инкапсуляции данных и RAII очень полезны оказались

Очень иронично звучат рассказы про инкапсуляцию в языке, где этой инкапсуляции нет, где приватные поля класса являются его скрытым интерфейсом, где любой использующий этот класс код неявно гоняет взад-вперед эти приватные поля, и изменение реализации приводит к необходимости перекомпилировать весь проект. И боже упаси по какой-то причине создать два конфликтующих набора конструкторов-операторов присвоения для одного и того же класса.

Два года назад я называл двумя главными минусами Си отсутствие RAII и плохое обобщенное программирование. Время идет, и мне уже не так нравится это самое RAII. Да, оно прикольно, если данные являются строго локальной памятью, но что делать, если мы работаем с файлами, где исключение может привести к необходимости закрыть файл, и закрытие файла может выбросить исключение? Мы можем отправить пост на LOR в деструкторе класса, но мы не можем обработать ошибку, возникшую при работе деструктора. При росте сложности системы системы растет сложность выделения и высвобождения ресурсов, но крестовое RAII не масштабируется — и это перечеркивает преимущества неявного RAII, который является единственной доступной опцией в C++. В реальных приложухах это значит, что при срабатывании исключения программа просто падает с концами — типичное такое крестовое приложение. Единственный способ решить проблему — это отказаться от RAII и обрабатывать ошибки явно в стиле Си.

byko3y ★★★★
()
Ответ на: комментарий от EugeneBas

POSIX-сокеты есть на всех *nix-системах, а виндовые сокеты не настолько отличаются от позиксовых, поэтому не соглашусь, что там настолько все страшно и сложно, что нельзя сделать кроссплатформенную обертку

Проблема вообще не в этом. Проблема в том, что сеть — это набор разношерстных механизмов, и задача пользовательской программы — стать клеем между ними. Самый элементарный пример — DNS. Типовое классическое никсовое приложение висло на много секунд, если DNS сервер не отвечал. Это было и под виндой тоже. И вот как сделать, чтобы такого не было — это задача сложная, ее нужно решать пользовательскому приложению, и она довольно мало отношения имеет к самой сети.

Функции «открыть дескриптор» и «прочитать из дескриптора байты» не имеет смысла вносить в стандартную либу C++, потому что они не имеют никаких преимуществ над аналогичными сишными функциями. Более того, я бы сказал, что уже имеющееся fstream значительно хуже stdio.h из-за абсолютно неадекватного базового механизма обработки ошибок ios и опоры на перегрузку битового сдвига — перегрузку, которую настолько тяжело грамотно гарантировать во всех модулях для собственных классов, что проще отказаться от нее и написать простые методы или функции для сериализации/десериализации.

у парней из Qt все давно получилось и работает https://doc.qt.io/qt-5/qtcpsocket.html

Почитал. Ничего у них не получилось. Из асинхронщины там только возможность зависнуть с таймаутом на одном дескрипторе. Stackoverflow прямо советует создавать потоки:
https://stackoverflow.com/questions/13677834/how-to-do-async-file-io-in-qt

А потоки — это на самом деле перекладывание сложности реализации асинхронного ввода-вывода на ядро системы, который там тоже асинхронно-событийный, но писаки ядра почему-то смогли этот механизм реализовать, а писаки Qt — нет. Цена такой абстракции — это куча лишних переключений контекстов и выделение намного большего числа объектов ядра на каждый запрос. По этой причине в 2021 все мало-мальски нагруженные сервера используют асинхронную обработку запросов.

byko3y ★★★★
()
Ответ на: комментарий от EugeneBas

Асинхронность - это всего лишь враппер поверх тех же сокетов и тредов. С помощью поллинга, очереди сообщений тред-пулла отлично организуется любая асинхронность

Так а разве executors не об этом? Пул потоков std::static_thread_pool, и sender-receiver для взаимодействия агентов.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Зачем ты продолжаешь позориться? Какой-то жсон, какой-то мусор-птр. Это просто невероятный уровень бездарности - сувать вектор в шптр.

Ну и да, даже в рамках этих жалких и нелепых оправданий - никаких проблем нет, а уж тем более в деструкторах.

nonedi18
()
Ответ на: комментарий от nonedi18

А ну я правильно задетектил скриптуха-адепта. Ну да, когда напишешь на эти «языках» что-то сложнее хеловорлда - приходи, расскажешь

Царь, я тебе разве не рассказывал, что много лет разрабатывал и поддерживал огромную блоатварь на Delphi? Странно, что ты мне это пишешь.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

И? С каких пор это перестало быть убогих хеловорлдом? Абсолютно насрать насколько «огромен» твой хеловорлд - он им останется. У тебя просто «интерпрейз-эдишен» версия, не более.

nonedi18
()
Ответ на: комментарий от nonedi18

Зачем ты продолжаешь позориться? Какой-то жсон, какой-то мусор-птр. Это просто невероятный уровень бездарности - сувать вектор в шптр

Пиши дальше свои микробенчмарки — зачем ты лезешь в разговор взрослых?

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Никто и ни в какой вселенной для чего-то нагруженного не использует асинхронный мусор. Меньше потребляй пропаганды для домохозяек.

К тому же понятия как «асинхронного ио» в принципе не существует. Оно значит тысячи всякой херни и практически всегда сводится блокировкам. Неважно на каком уровне реализованным.

А асинхронным оно называется только потому, что использует маня-асинхронное апи ядра. Которое нихрена не асинхронное, а просто не блокирующие.

При этом оно так же нихрена не является неблокирующем - оно так же является блокирующим просто через пультиплексер. Единственная попытка от этого отойти - урина в полинг-режиме. И то это такая себе затея.

При этом никакая асинхронная логика не может быть быстрой, а уж тем более не может в нагрузку, т.е. в пропускную способность. В неё может только синхронная логика. Вся логика в этой вселенной - синхронная, либо она мусор.

Поэтому сетевуха синхронная, процессор синхронный, твой мусорный сетевой стек синхронный. Как и мультиплексор.

nonedi18
()
Ответ на: комментарий от anonymous

Никаких возражений, ни одного слова по теме. Он просто видит оппонента, с которым он не может спорить по причине своей полной некомпетентности и начинает требовать забанить оппонента.

Siborgium ★★★★★
()
Ответ на: комментарий от EugeneBas

POSIX-сокеты есть на всех *nix-системах, а виндовые сокеты не настолько отличаются от позиксовых

но все надо делать поступательно и было бы очень здорово хотя бы иметь просто кроссплатформенный сокет в стандрате

Для чего, если все и так практически одинаково?

а поверх навернуть асинхронность всегда можно будет.

Нет, потому что как раз асинхронность оказывается уже очень разной – если, конечно, не завязываться на убогий select.

Siborgium ★★★★★
()
Ответ на: комментарий от byko3y

и изменение реализации приводит к необходимости перекомпилировать весь проект.

Это естественно для не-managed языка.

и закрытие файла может выбросить исключение?

То ты дописываешь try-catch вокруг file.close().

В своих деструкторах также можно использовать uncaught_exceptions, и не выбрасывать исключений, если деструктор вызывается в процессе раскрутки стека. В противном случае throw в деструкторе НЕ приведет к terminate.

Siborgium ★★★★★
()
Ответ на: комментарий от byko3y

Да-да, я уже вижу причину недопонимания.

И наверняка ошибаетесь в своих предположениях.

Ты предполагаешь, что std::variant будет хранить банальное <bool, int, double>, я же скорее имел в виду какое-нибудь дерево JSON с

Я предполагаю, что вы покажете конкретный пример и укажите на возможные места возникновения неких ошибок. Но вместо этого вы выдаете очередной графоманский опус с нагнетанием эмоций.

Так что прошу вас еще раз: покажите пример, который бы продемонстрировал эти ваши гипотетические ошибки.

Заодно посмотрите, чем отличается поведение dynamic_cast<T&> от dynamic_cast<T*>. Может узнаете, что невозможность приведения не обязательно должна вести к исключению.

eao197 ★★★★★
()
Ответ на: комментарий от byko3y

Я твоего опыта не знаю, так что извиняй.

О чужом опыте заикается нонейм-графоман, который не способен написать внятный и связный текст?

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

где этой инкапсуляции нет

Ну нет, так нет.

У кого-то вот явно мозгов нет, и, как видно из очередных ваших простыней бреда, вам это не мешает.

eao197 ★★★★★
()
Ответ на: комментарий от Siborgium

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

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Если бы царь не переходил очень быстро в режим «голубя за шахматной доской» цены бы ему не было.

anonymous
()
Ответ на: комментарий от anonymous

Если бы царь не переходил очень быстро в режим «голубя за шахматной доской» цены бы ему не было.

И не грубил и деньги в дом носил …

anonymous
()
Ответ на: комментарий от byko3y

Почитал. Ничего у них не получилось.

Я Qt-реализацию приводил как пример синхронного, но кроссплатформенного сокета.

Функции «открыть дескриптор» и «прочитать из дескриптора байты» не имеет смысла вносить в стандартную либу C++, потому что они не имеют никаких преимуществ над аналогичными сишными функциями.

переносимость

А потоки — это на самом деле перекладывание сложности реализации асинхронного ввода-вывода на ядро системы А под капотом экзекьюторов по-твоему потоков не будет?

EugeneBas ★★
()
Ответ на: комментарий от byko3y

Так а разве executors не об этом? Так а я о чем и вещаю! В стандарте уже есть все ингредиенты для того, чтобы по-быстрому собрать какой-то асинхронный механизм, если добавят готовый - я буду только рад. А вот примитива для общения по сети, ака сокет, на который можно навернуть эту асинхронность - нет. Но асинхронность и сеть - это хорошо друг друга дополняющие вещи, но в общем случае никак не связанные. Поэтому я и говорю, что хочу видеть сокет в стандарте.

EugeneBas ★★
()
Ответ на: комментарий от Siborgium

Для чего, если все и так практически одинаково?

для того же, для чего завезли в стандарт потоки, мьютексы и файловую систему - для лучшей переносимости, не более

не завязываться на убогий select

чем уж так select не угодил?

EugeneBas ★★
()
Последнее исправление: EugeneBas (всего исправлений: 1)
Ответ на: комментарий от EugeneBas

для того же, для чего завезли в стандарт потоки, мьютексы и файловую систему - для лучшей переносимости, не более

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

чем уж так select не угодил?

Он не скейлится.

Siborgium ★★★★★
()
Ответ на: комментарий от EugeneBas

Я Qt-реализацию приводил как пример синхронного, но кроссплатформенного сокета

Синхронный кроссплатформенный сокет пишется студентом за несколько часов.

Siborgium ★★★★★
()
Ответ на: комментарий от EugeneBas

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

Очень даже связанные: второе без первого нужно только для хелловорлдов.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Синхронный кроссплатформенный сокет пишется студентом за несколько часов.

также как и кроссплатформенные потоки и мьютексы

EugeneBas ★★
()
Ответ на: комментарий от Siborgium

Синхронный кроссплатформенный сокет пишется студентом за несколько часов.

Тута вам поставлю

,

Ящик пива, может быть за несколько часов и выпьют …

anonymous
()
Ответ на: комментарий от EugeneBas

также как и кроссплатформенные потоки и мьютексы

Да врядли. Мьютексы в Qt реализовывали самостоятельно, это не просто вызов системных примитивов. Благодаря чему в Qt был shared_mutex для Windows 2000 или типа того, если мне память не изменяет. Да и в стандартном С++ приходилось реализовывать самостоятельно для поддержки Windows XP. Также как и boost::mutex

В системе такие примитивы появились только с Windows 7(примитивы системы работают быстрее чем самопальные реализации в библиотеках):

https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-tryacquiresrwlockexclusive

https://stackoverflow.com/a/878228/4544798

Благодаря огромному труду разработчиков библиотек, которые реализовали «полифилы» для привычных API для устаревших систем постоянно натыкаюсь на всякие посты типа «Почему программа стала требовать новую версию Windows, ведь в Windows 95 уже были все функции на все случаи жизни, и дальше разработчики Windows ничего не делали, а лишь меняли обои в течение последних 25 лет?».

fsb4000 ★★★★★
() автор топика
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от fsb4000

Ну qt с бустом свои цели, у коммитета - свои, а мы сейчас про коммитет. И стандартный std::thread - это не более чем переносимя обертка над нативными тредами, под линуксом даже без -lpthread не соберется.

EugeneBas ★★
()
Ответ на: комментарий от Siborgium

Это естественно для не-managed языка

Ноуп. В сишке такого нет. Делаешь typedef struct some_data * SomeData;, инкапсулируешь всю работу с ней в функции, и вуаля — ты можешь менять поля в SomeData как угодно, а реализация этого не заметит, ее даже перекомпилировать не нужно будет, они будет зависеть только от публичных методов.

То ты дописываешь try-catch вокруг file.close()

Ну ты скатываешь в сишный стиль, ведь это уже не RAII.

В своих деструкторах также можно использовать uncaught_exceptions, и не выбрасывать исключений, если деструктор вызывается в процессе раскрутки стека. В противном случае throw в деструкторе НЕ приведет к terminate

Хах. И как же тогда планировать логику обработки исключения в таких ситуациях? У тебя код деструктора мог выбросить исключение в надежде, что кто-то обработает этот конкретный класс, но ты тем временем обрабатываешь совсем другую ошибку.

byko3y ★★★★
()
Ответ на: комментарий от eao197

Я предполагаю, что вы покажете конкретный пример и укажите на возможные места возникновения неких ошибок. Но вместо этого вы выдаете очередной графоманский опус с нагнетанием эмоций
Так что прошу вас еще раз: покажите пример, который бы продемонстрировал эти ваши гипотетические ошибки

Ну ты же понимаешь, что я не буду писать экран кода в том стиле, который ты мне предложил? Причем. ты сам согласен с тем, что даже для простых случаев реализация на std::visit сильно больше, чем это нужно. А неточный матчинг, который предлагаю я, не реализован в стандарте и для него нужно писать кучу реализации этого самого неточного матчинга.

Заодно посмотрите, чем отличается поведение dynamic_cast<T&> от dynamic_cast<T*>. Может узнаете, что невозможность приведения не обязательно должна вести к исключению

При чем тут dynamic_cast? Это не контейнер, а я писал про контейнеры. Например, variant<const int> и variant<int> — это два несовместимых типа в C++.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Ну ты же понимаешь, что я не буду

Я понимаю, что вы – типичное форумное трепло. Как выплеснуть страницу собственной боли от того, что реальность противоречит вашей тонкой внутренней организации – так это вы запросто. А вот как ответить за собственные слова, так «ну ты же понимаешь, что я не буду».

Причем. ты сам согласен с тем, что даже для простых случаев реализация на std::visit сильно больше, чем это нужно.

Напомню, что мы говорим не про std::visit, а про паттерн-матчинг, в котором вы усмотрели какие-то загадочные проблемы.

А неточный матчинг, который предлагаю я

Стоп. Где и что вы предлагаете мне не ведомо. Вы начали говорить про проблемы паттарн-матчинга в C++. Вас попросили привести пример. И… Где, блин? Сколько можно вас об этом просить?

При чем тут dynamic_cast?

Это штатная проверка в C++ на то, что мы имеем тот тип, который хотели бы иметь. В run-time.

Это не контейнер, а я писал про контейнеры.

Ну вот я совершенно хз о чем вы писали. Потому что следующее предложение, а именно:

Например, variant<const int> и variant<int> — это два несовместимых типа в C++.

наводит на мысль о том, что вы вообще не понимаете о чем говорите. Ибо если бы понимали, то привели бы пример кода, а не несли херню, которую еще как-то нужно расшифровать.

eao197 ★★★★★
()
Ответ на: комментарий от EugeneBas

Я Qt-реализацию приводил как пример синхронного, но кроссплатформенного сокета

В стандартной либе крестов как минимум до C++11 (а то и позже) не было поддержки КЛАВИАТУРЫ И ЭКРАНА, а ты про сокеты ноешь.

byko3y ★★★★
()
Ответ на: комментарий от fsb4000

В системе такие примитивы появились только с Windows 7(примитивы системы работают быстрее чем самопальные реализации в библиотеках)

Я отвечал недавно, что это вызвано не магией родных примитивов винды, а тот факт, что в Boost синхронизация выполнена по большей части «на отлюбись». Именно потому я для своей либы писал собственные механизмы синхронизации. Все базовые механизмы синхронизации на стороне ядра были в винде начиная как минимум с NT 4, единственный новый механизм ядра с тех пор — это WakeByAddressXXX и WaitOnAddress, которые были реализованы скорее для совместимости с линевым futex.

https://stackoverflow.com/a/878228/4544798

The current version of boost::mutex uses neither a Win32 CRITICAL_SECTION, nor a Win32 Mutex. Instead, it uses atomic operations and a Win32 Event for blocking waits

Это один в один реализация критических секций в kernel32.dll. Я тоже в своих блокировках для виндовой версии многое скопипастил из виндовой реализации.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Ноуп. В сишке такого нет. Делаешь typedef struct some_data * SomeData;

ВНЕЗАПНО то же самое можно сделать и в С++, не говоря уже об pimpl-idiom.

Ну ты скатываешь в сишный стиль, ведь это уже не RAII.

Ты скатываешь в демагогию.

  1. В RAII в деструкторах при раскрутке стека выброс исключения не обрабатывается должным образом, а вызывает terminate
  2. RAII бесполезен.

Поможем Даше найти логическую связь между двумя тезисами.

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

И как же тогда планировать логику обработки исключения в таких ситуациях?

Не понял вопроса. Если у тебя идет раскрутка стека, то ты уже ничего сделать не можешь. Так вместо падения ты, по крайней мере, можешь вывести сообщение о том, что все пропало.

У тебя код деструктора мог выбросить исключение в надежде, что кто-то обработает этот конкретный класс, но ты тем временем обрабатываешь совсем другую ошибку.

Что-то мне подсказывает, что ты понятия не имеешь, о чем я говорю. Осиль, пожалуйста, соотв. страничку.

Siborgium ★★★★★
()
Ответ на: комментарий от byko3y

При чем тут dynamic_cast? Это не контейнер, а я писал про контейнеры. Например, variant и variant — это два несовместимых типа в C++.

Потому что, ВНЕЗАПНО, int и const int это два несовместимых типа в С++. Никому не нужен «неточный матчинг». Если ты пользуешься каким-то свойством базового типа, достаточно просто делать std::remove_cvref_t<T>.

Siborgium ★★★★★
()
Ответ на: комментарий от eao197

Напомню, что мы говорим не про std::visit, а про паттерн-матчинг, в котором вы усмотрели какие-то загадочные проблемы.

А неточный матчинг, который предлагаю я

Стоп. Где и что вы предлагаете мне не ведомо. Вы начали говорить про проблемы паттарн-матчинга в C++. Вас попросили привести пример. И… Где, блин? Сколько можно вас об этом просить?

https://github.com/mpark/patterns — например. Мне все цитировать или можно избранные? Например

std::string s = "large";

using namespace mpark::patterns;
match(s)(
    pattern(anyof("big", "large", "huge")) = [] { std::cout << "big!\n"; },
    pattern(anyof("little", "small", "tiny")) = [] { std::cout << "small.\n"; },
    pattern(_) = [] { std::cout << "unknown size.\n"; });

Но это пока что hello world. Если вместо констант «big», «large» мы вызываем функции:

std::string s = "large";

using namespace mpark::patterns;
match(s)(
    pattern(anyof(get_big(), get_large(), get_huge())) = [] { std::cout << "big!\n"; },
    pattern(anyof(get_little(), get_small(), get_tiny())) = [] { std::cout << "small.\n"; },
    pattern(_) = [] { std::cout << "unknown size.\n"; });

то в функциях могут произойти исключения. Причем, проблему заметил не только я:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2381r0.html

Правда, и этот автор тоже заметил ее не до конца, поскольку проблему исключений в условиях матчинга он не поднял. А исключение может произойти и в operator==, в конце-концов — это если говорить о том, насколько убоги в крестах перегрузки операторов.

А что ты будешь делать, если при присвоении std::variant у тебя происходит исключение и ты остаешься с valueless_by_exception? Я так догадываюсь, что в твоем личном коде все подобные ветви ошибок тщательно проработаны и отлажены.

При чем тут dynamic_cast?

Это штатная проверка в C++ на то, что мы имеем тот тип, который хотели бы иметь. В run-time

Например, variant<const int> и variant<int> — это два несовместимых типа в C++.

наводит на мысль о том, что вы вообще не понимаете о чем говорите. Ибо если бы понимали, то привели бы пример кода, а не несли херню, которую еще как-то нужно расшифровать.

Я изначально вел разговор про несовместимость шаблонов с разными модификаторами, а не классов. Как мне поможет dynamic_cast в том коде?

https://gcc.godbolt.org/z/dW881sseo

#include <vector>
#include <memory>

using namespace std;

typedef shared_ptr<int> Node;
typedef shared_ptr<const int> ConstNode;
struct Array {
    std::vector<ConstNode> children;

    virtual void append_children(const std::vector<ConstNode> new_children)
    {
        children.insert(end(children), begin(new_children), end(new_children));
    }
};

std::vector<Node> user_input()
{
    return std::vector<Node>();
}

int main()
{
    Array arr;

    auto input = user_input();
    arr.append_children(input);
    return 0;
}
byko3y ★★★★
()
Ответ на: комментарий от Siborgium

ВНЕЗАПНО то же самое можно сделать и в С++, не говоря уже об pimpl-idiom

Ну так а я о чем? Сишка лучше. Класс на pImpl выглядит страшнее, чем сишный аналог через forward declaration и функции.

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

«Воспользуешься механизмом» — это и есть «откажешься от RAII в этом участке кода». То есть, заменишь деструктор на какой-нибудь close(). И вот у тебя уже два механизма высвобождения ресурса. А чтобы сократить сложность, ты сократишь две механизма до одного — очевидного close и пустого деструктора. Вот весь RAII и закончился.

И как же тогда планировать логику обработки исключения в таких ситуациях?

Не понял вопроса. Если у тебя идет раскрутка стека, то ты уже ничего сделать не можешь. Так вместо падения ты, по крайней мере, можешь вывести сообщение о том, что все пропало

Как это не могу? А try-catch — это что тогда? Другое дело, что катастрофический отсос C++ заключается в отсутствии try-finally (который есть в MSVC в качестве расширения, к слову), где я бы в finally блоке вызывал то самое close(), проверял его статус и дальше принимал решение — только RAII, только неявный алгоритм финализации.

У тебя код деструктора мог выбросить исключение в надежде, что кто-то обработает этот конкретный класс, но ты тем временем обрабатываешь совсем другую ошибку.

Что-то мне подсказывает, что ты понятия не имеешь, о чем я говорю. Осиль, пожалуйста, соотв. страничку

std::uncaught_exception позволяет не бросать исключение, но оно не позволяет подменить старое исключение новым, требующим обработки, или передать наверх оба исключения. То есть, внутреннее исключение всегда имеет приоритет. Это что-то типа реализации CRDT по принципу «последний писатель выигрывает». Ну типа в простейших случаях этот костыль прокатывает, но когда мы хотим безупречно обработать все острые углы, то это не прокатывает, нужно грамотная логика, а std::uncaught_exception ее не дает, оно просто затирает новое исключение старым. С таким подходом можно просто развешивать пустые catch {} — ну а че, мы все равно их толком не обрабатываем?

byko3y ★★★★
()
Ответ на: комментарий от Siborgium

Потому что, ВНЕЗАПНО, int и const int это два несовместимых типа в С++. Никому не нужен «неточный матчинг». Если ты пользуешься каким-то свойством базового типа, достаточно просто делать std::remove_cvref_t<T>

Однако же, я могу спокойно присваивать между этими типами, и даже превращать int& в const int&, но не могу делать аналогичные вещи для производных шаблонов.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Боже, этот поехавший 10 раз уже опозорился, но продолжает.

то в функциях могут произойти исключения.

Да ты чё. А ещё исключение может произойти в switch(get_govno()). А как же так?

Причем, проблему заметил не только я:

Ты, бот. Просто нанёс херни. Обгадился, а после побежал гуглить. И просто пастишь левую херню с похожими ключевыми словами. Ты хотел показать исключения в деструкторах - валяй.

Если кому сложно прочитать/понять что написано в ссылке на которую этот поехавший ссылается - я поясню. Там говорится о том, что в случае использования result/throw получается разная семантика. Это полнейшая чушь, потому как это не разная семантика, а базовое свойство исключений - они везде себя так ведут. Это примерно как блеять foo(result()) - вызывает foo, а foo(throw()) - нет. Ахренеть какие новости.

Автор просто хочет, чтобы inspect ловил исключения и по ним можно было матчить. Никаких «проблем» там нет. Ни о каких проблемах автор не заявляет. Проблемы у него обусловлены тем, что ему «не красиво», «не привычно» и «не консистентно». Т.е. это локальная шиза result-адепта.

nonedi18
()
Ответ на: комментарий от byko3y
int main()
{
return 0;
typedef shared_ptr<const int> ConstNode;

typedef
using namespace std;
virtual
const std::vector<ConstNode> new_children
return std::vector<Node>();

Это не менее чем терминальная. Бот пастит рандомную херню и выдаёт её за код. Иначе это не объяснить. Это уровень школьника, которому дали методичку и который с ней игрался пару уроков.

nonedi18
()
Ответ на: комментарий от byko3y

У тебя там как с методичкой? На что я возражать должен? На потоки бездарного бреда. На другую часть, где ты хотя бы код своровал - я ответил.

Смысла в самой потуги нет. Вообще. Где-то спастил какую-то херню с const и побежал. Схема такая же как обычно.

Ладно там уровень нулевой, но балабол даже не попытался хоть как-то объяснить что он вообще пытался сделать.

Какие-то модификаторы, какая-то несовместимость - это понос. Это ничего не значит. Потому как никаких модификаторов нет, а уж тем более какой-либо несовместимости.

Там нечего «совмешаться». Судя по всему бот где-то увидел ссылки, либо херню уровня const int = int;

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

Мне даже лень что-либо объяснять подобному.

nonedi18
()
Ответ на: комментарий от byko3y

Ну так а я о чем? Сишка лучше. Класс на pImpl выглядит страшнее, чем сишный аналог через forward declaration и функции.

Опять бред. Тебе что-то мешает в плюсах использовать forward declaration и функции?

Ты сам следишь за тем, что пишешь?

  1. В C есть forward declarations и функции.
  2. В C/C++ есть forward declarations и функции, а еще pimpl-idiom.

Дальше ты говоришь, что «сишка лучше». Ты в порядке?

«Воспользуешься механизмом» — это и есть «откажешься от RAII в этом участке кода». То есть, заменишь деструктор на какой-нибудь close(). И вот у тебя уже два механизма высвобождения ресурса.

Нет, у меня один механизм высвобождения ресурса – деструктор будет дергать этот же close().

А чтобы сократить сложность, ты сократишь две механизма до одного — очевидного close и пустого деструктора. Вот весь RAII и закончился.

Нет, не сокращу – я потеряю exception safety и буду вынужден руками вызывать сlose, а в 99% случаев мне глубоко наплевать, удачно отработает close или нет – потому что если close отрабатывает неудачно, то что-то уже пошло совсем не так.

Siborgium ★★★★★
()
Ответ на: комментарий от Siborgium

Опять бред. Тебе что-то мешает в плюсах использовать forward declaration и функции?

Нет. Просто, это уже не плюсы. Я еще могу взять stdio, писать на одних структурах, и вообще не применять ни одной крестовой фишки. И это вроде как C++ по-твоему, да? А по-моему это уже вполне себе «сишка» и она «лучше».

Нет, у меня один механизм высвобождения ресурса – деструктор будет дергать этот же close()

М-м-м, идемпотентные методы с зомби-объектами, как вкусно. Правда, я пока что не понял, как на этом фоне будет обрабатываться СЛОЖНАЯ логика обработки исключения.

в 99% случаев мне глубоко наплевать, удачно отработает close или нет

Суть крестовой обработки ошибок.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Нет. Просто, это уже не плюсы. Я еще могу взять stdio, писать на одних структурах, и вообще не применять ни одной крестовой фишки. И это вроде как C++ по-твоему, да? А по-моему это уже вполне себе «сишка» и она «лучше».

Ты же в курсе что Android Libc и Windows Libc написаны на С++?

С настолько лучше, что даже разработчики стандартной библиотеки С выбирают С++ 🤣

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.