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
Да.
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-ного кейса.
KosBeg
Ivan
Может он как хеш таблица работает?
Constantine
Ivan
Тогда О(1)
Andrei
Constantine
O(log N) показывает Беркус
Ivan
Я всегда проверяю -О0
Berkus
Constantine
ну очевидно что компилятор пока строит дерево поиска
Andrei
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 они без оптимизаций примерно одинаковый код дают
Berkus
Andrei
Сравнение работает быстрее.
Berkus
.unwrap() => {
if (err) handler();
return T;
}
handler() = panic();
KosBeg
Matwey
Ivan
Короче, скажите да. Switch в худшем случае работает за О(N)
Andrei
Да.
Constantine
Я не спорю что вся механика Result<> очень хороша при наличии do-нотации и если надо заставлять проверять ошибки, это просто совершенно не тот случай
Constantine
Здесь скорее нужен variant<enum, callback> как параметр
Berkus
ну оно и без do-нотации зачудительно работает
Berkus
Vladislav
очень частично
Berkus
Berkus
в примерах написано
#include <mpark/match.hpp>
Berkus
так тебе шашечки или ехать?
Evgenii
должно быть в модуле
Matwey
И модули уже завезли? Я просто был в спячке тут долгое время
Ivan
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
Anonymous
https://stackoverflow.com/questions/6352123/multiple-directories-under-cmake
Anonymous
Я взял пример отсюда