Andrei
В худшем случае.
Ivan
Я читал про это, но решил проверить
Constantine
там не исключение если что
А что там? В чем принципиальная разница между "функция вернет значение или бросит исключение" и "функция вернет сложный объект как значение"?
Berkus
cmp eax, 91 je .L3 cmp eax, 91 jg .L4 cmp eax, -1 je .L5 cmp eax, 3 je .L6 jmp .L2 вот твой свитч - иф-джамп-иф-джамп
Ivan
То есть О(N)?
Andrei
Да.
KosBeg
Какая разница? Условия-то надо всё равно все перебрать.
нет, немного не так как в ифах, свитч быстрей (как асемблерщик говорю)
Berkus
cmp eax, -1 je .L5 cmp eax, 3 je .L6 jmp .L2 .L4: cmp eax, 69199 je .L7 cmp eax, 1255125 je .L8 jmp .L2 он еще смешно поделил пополам по значению 91
Andrei
Низачем. Это просто конструкция языка. Все равно будет n проверок для n-ного кейса.
Ivan
Может он как хеш таблица работает?
Ivan
Тогда О(1)
Andrei
нет, немного не так как в ифах, свитч быстрей (как асемблерщик говорю)
Конечно не так, но вопрос-то был про асимптотику.
Berkus
зависит от компилятора :D
ну естественно, и от опций компиляции
Constantine
O(log N) показывает Беркус
Ivan
Я всегда проверяю -О0
Berkus
O(log N) показывает Беркус
да, близко к тому
Constantine
ну очевидно что компилятор пока строит дерево поиска
Andrei
O(log N) показывает Беркус
Это легко ломается же.
Constantine
видимо, для 100 значений он будет вычислять переход, но это не точно
Andrei
Сделайте порядок в switch-e другой и break уберите.
Andrei
И ему ничего не останется как сделать честные O(n) проверок.
Ivan
Так интереснее
Berkus
cmp esi, 91 je .L3 jg .L4 -Ofast сделал немного peephole оптимизаций убрав релоады
KosBeg
зависит от компилятора(и флагов как подсказали). jump table быстрей чем if, но если просто сравнение - то тоже самое по сути
Berkus
но в целом история та же
Andrei
Логарифм там только для break в каждом кейсе. Тогда действительно, поскольку свитч только для целых на которых есть сравнение.
Constantine
Кстати, Беркус, а как в случае возврата Result<T, Error> глобально переопределить действие при ошибке?
Berkus
Constantine
Ты же полностью на клиента перекладываешь заботу об ошибке
Andrei
Jump table не то чтобы обязательно быстрее. Поход в память штука дорогая.
Ivan
Я проверял на ICC, clang, GCC они без оптимизаций примерно одинаковый код дают
Andrei
Сравнение работает быстрее.
Berkus
.unwrap() => { if (err) handler(); return T; } handler() = panic();
Constantine
глобально задавай handler для unwrap()
template <...> global_unwrap_handler()
Matwey
глобально задавай handler для unwrap()
Это теперь чат про rust?
Berkus
Это теперь чат про rust?
нет, перетаскиваем best practices
Ivan
Короче, скажите да. Switch в худшем случае работает за О(N)
Andrei
Да.
Constantine
Я не спорю что вся механика Result<> очень хороша при наличии do-нотации и если надо заставлять проверять ошибки, это просто совершенно не тот случай
Constantine
Здесь скорее нужен variant<enum, callback> как параметр
Berkus
ну оно и без do-нотации зачудительно работает
Matwey
нет, перетаскиваем best practices
А паттерн матчинг уже завезли в C++?
Vladislav
очень частично
Matwey
да, конечно
Это мне по нраву
Berkus
в примерах написано #include <mpark/match.hpp>
Berkus
так тебе шашечки или ехать?
Evgenii
должно быть в модуле
Matwey
И модули уже завезли? Я просто был в спячке тут долгое время
Ivan
))
Nik
Вопрос: У меня есть кастомное исключение, которое принимает кастомный enum class ErrorCode, хранит в себе unordered_map<ErrorCode, string/*Строка с описанием проблемы*/>. При вызове what() возвращаеься строка с описанием соответствующей проблемы.
Nik
Теперь мне нужно чтобы в строке было еще и текущее состояние объекта. Ну там, типа "Network interface" + networkInterface.to_string() + is not supported";
Nik
А передавать обычный эксепшн со строкой вызывает дублирование кода. Ну, эксепшн с одной и той же портянкострокой проблемы пришлось бы вызывать в 15 местах и все такое
Nik
Думаю просто хранить объект эксепшена в классе из которого я его буду кидать, чтобы эксепшн знал о внутреннем состоянии класса
Nik
А, вопрос
Nik
Почему я так ублюдочно это все делаю и как лучше?
Nik
Просто тогда я во многих местах буду дублировать код, пишучи throw myException("Описание проблемы на 100500 строк" + currentValue1 + "Еще 100500 строк" + currentValue2); И я бы хотел чтобы логика конструирования строки была внутри самого what() Плюс мне надо в эксепшене хранить ретурнкод с которым программа должна завершиться
Nik
А он как раз определяет какое сообщение об ошибке
Nik
Да, допер
Nik
Спс
Constantine
хм... а что если я буду вместо коллбека передавать что-то такое template <typename DefaultOptionsType, /*сигнатура функции*/> struct customizable_dispatcher { //конструкторы в стиле variant<DefaultOptionsType, function</*сигнатура функции*/>> /*возврат из сигнатуры функции*/ operator ()(function</*сигнатура функции плюс параметр DefaultOption*/> defaultCallback, /*параметры из сигнатуры функции*/){ //проверить variant и либо вызвать функцию, либо defaultCallback с соответствующей опцией } };
Constantine
хм... наверное даже не function(/**/) а просто указатель на функцию, потому что параметров принципиально должно быть достаточно
Constantine
Вроде как в 99% случаев создание объекта потеря времени
Constantine
Речь о поведении при ошибке по умолчанию, user-defined option разумеется <s>всегда лямбда</s> function
Constantine
что за велосипед на этот раз я изобрел?)
Constantine
потому что в этом случае я не смогу написать унифицированную версию throw_exception
Vladislav
слишком просто
Constantine
смотри, текущая реализация делает так enum class error_action_enum { skip = 0, assert = 1, exception = 2 };
Constantine
std::vector<uint8_t> readFile(filename, error_action_enum)
Constantine
как только сделают модули компиляции в С++ я сделаю этот параметр шаблонным)
Anonymous
Доброй ночи :) "Маленькая" (наверное) жопа со сборкой проекта через cmake (https://pastebin.com/1PMENFNb) В случае с g++ -std=c++11 .... все без проблем собирается Как можно решить? :( (Если нужны CMakeLists - могу скинуть)
Constantine
смотри, текущая реализация делает так enum class error_action_enum { skip = 0, assert = 1, exception = 2 };
так вот, чудо этой реализации в том, что exception сам выбирает, какого типа exception бросить
Anonymous
https://stackoverflow.com/questions/6352123/multiple-directories-under-cmake
Anonymous
Я взял пример отсюда