LINUX.ORG.RU

Почему boost::optional еще не в стандартной библиотеке?

 , , ,


0

6

Я начал писать очередной хеллоуворлдный физзбазз, хочу написать функцию, которая находит путь в графе слов, если он там есть. Соответственно хочу вернуть или std::vector<std::string>, если путь найден, или ничего не возвращать. Что же мне теперь делать, тянуть буст в зависимостях? Или исключение кидать? А может что-то еще более наркоманское, типа умного указателя на этот самый вектор, и если не получилось, то указатель пусть будет равен нулю?

На самом деле плохо представляю, как вообще кодить без boost::optional и boost::variant. Разве что вместо второго городить везде классы и наследование.

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

Мне надо на C++, тестовое задание чтобы работу найти. И вроде даже в Java это уже считается моветоном среди не ретроградов. Помню, что даже там уже Optional придумали.

hlebushek ★★
() автор топика

Что же мне теперь делать, тянуть буст в зависимостях?

Наркоман?

// bla-bla
// .... 

// nothing found
return {};
DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от hlebushek

Хм, я учил Java тогда, когда ещё 7-ка была. Увы, новее знаю плохо, ибо на самообучении при _очень_ редком применении.

Хотя да, нашёл Optional в javadoc'ах 8-ки.

Deleted
()
Последнее исправление: merhalak (всего исправлений: 1)

Видимо остается городить свой класс, как re.match в бидоне, который будет делать

auto found = sdelay_iz_muhi_slona(dictionary, startWord, endWord);
if found.nashel() {
    std::cout << "Ura, nashol put', vot on: " << found.path_as_string() << std::endl;
}
else {
    std::cerr << "Ne nashel :{" << std::endl;
}
hlebushek ★★
() автор топика
Ответ на: комментарий от DELIRIUM

Хипстеры, сэр.

Ты смотри, даже меня уже ретроградом в мои то 20, назвали.

Deleted
()

может что-то еще более наркоманское

Возвращай тупл литералом и разворачивай его через std::tie , будет почти как в go.

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

То, что некрасиво, нет такого, что как Optional - сразу понятно из сигнатуры, что оно возвращает и когда, и всё такое.

hlebushek ★★
() автор топика

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

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

Предлагаешь возвращать либо мусорный вектор и значение enum class'а, означающее провал, либо хороший вектор и значение enum class'а, означающее удачу?

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

Java, говоришь? http://www.oracle.com/technetwork/articles/java/java8-optional-2175753.html

Любые указатели (хоть unique_ptr/shared_ptr в С++, хоть «ссылки» в Java) - ни разу не адекватная замена optional, ибо

  • Как узнать, что оно может быть null? Комментарий - не надёжно.
  • accidental data structures
  • быстродействие (в C++ заворачивание в optional может быть на порядок быстрее, чем выделение динамической памяти)

Первые два пункта касаются Java в той же мере, что и С++.

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

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

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

Любые указатели (хоть unique_ptr/shared_ptr в С++, хоть «ссылки» в Java) - ни разу не адекватная замена optional, ибо

Как узнать, что оно может быть null? Комментарий - не надёжно.

Не отрицая полезности optional, к любому *_ptr следует относиться так, будто он может быть nullptr.

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

А если внезапно мне надо не вектор возвращать, а свой собственный класс, у которого не бывает пустого значения?

hlebushek ★★
() автор топика
Ответ на: комментарий от hlebushek
return std::make_pair(true, result); // Нашёл
return std::make_pair(false, {}); // Не нашёл

Говно конечно, но примерно того же сорта, что и твой вариант.

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

А если внезапно мне надо не вектор возвращать, а свой собственный класс, у которого не бывает пустого значения?

Тогда, очевидно, этот способ не подходит и тебе придется просто плакать в уголке. Ну или возвращать, скажем, указатель.

А вообще, тебе предлагают решение, а ты капризничаешь «а вот сичас у миня ни палучицца!!!11».

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

Больше литералов же, покажем что мы могем как в питоне:

return {true, res};
return {false, {}};
anonymous
()
Ответ на: комментарий от tailgunner

«Параноидальный» подход к ptr порождает 100500 лишних if (not null), else-ветка которых далеко не всегда тривиальна.

Учитывая, что вариант с нехваткой памяти можно исключить из рассмотрения (один фиг new умеет throw bad_alloc), остаётся преднамеренный возврат null. Возможный преднамеренный возврат null - это сколько процентов от возвратов указателей вообще? Допустим, 30%. Остальные 70% if будут мертвым кодом.

anonymous
()
Ответ на: комментарий от hlebushek
boost::optional<Date> begin, end;
boost::tie(begin, end) = getPeriod();

It works because inside boost::tie a move-assignment from T is invoked on optional<T>, which internally calls a move-constructor of T.

Бустокислота же, неудивительно что ее в stdlib не приняли.

пустого значения у объекта, который иногда хотим возвращать, не бывает

Плохой, негодный объект. Сделай placement new в aligned storage и возвращай этот storage. А когда тебя придут бить клавиатурами коллеги - скажи что ты так аллокаций избегаешь.

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

Бустокислота же, неудивительно что ее в stdlib не приняли.

Ее собираются принять. Не совсем бустовый вариант, правда.

tailgunner ★★★★★
()

Тред не читал, никто ещё не предложил обмазаться экспериментальным разделом 14ого стандарта?

pon4ik ★★★★★
()

Вообще свой optional(у мну на проекте как раз свой закостылен, ибо в интерфейсах таскается) дело ну пары часов с тестами медитацией и перервывом на просмотр порно.

pon4ik ★★★★★
()

возвращай shared_ptr

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

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

Спасибо - не знал.

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

Плохой, негодный объект

Отличный объект. Default-конструкторы - в общем случае отстой. Как раз optional отлично сочетается с отказом от default-конструкторов.

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

А как это работает в boost::optional без пойнтеров?

Я хотел посмотреть, открыл optional.hpp и перехотел. Размер возвращаемого объекта из функции фиксируется в компайлтайме же. Они возвращают struct {bool = false} для None и struct {myclass = result} для Some, выбираемые темплейтной магией?

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

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

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

А как это работает в boost::optional без пойнтеров?

Не знаю. У меня нет ни Boost, ни C++14.

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

Мальчик, иди разберись для начала, сколько байт занимает std::vector.

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

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

Бывают объекты размером не больше указателя, их как раз нужно возвращать по значению

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

Бывают объекты

Бывают, лол, все контейнеры, все виды строк и все PIMPL'ы (т.е. все Qt). Интересно как раз в каком случае НЕ нужно по значению возвращать.

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

Да даже если объект в несколько раз больше указателя - возврат по значению будет намного быстрее, чем работа с динамической памятью. Вобщем-то достаточно типовая ситуация: объект представляет из себя набор из пары-тройки указателей плюс какой-нибудь size_t. RVO и move semantics делают возврат по значению выгодным, ибо данные, на которые ссылаются внутренние указатели объекта, не копируются.

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

Бывают, лол, все контейнеры

Не все

, все виды строк

не вск

и все PIMPL'ы (т.е. все Qt).

Далеко не все классы в Qt используют PIMPL, особенно те из них, которые не наслудуются от QObject

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

Принимается, но в таких слуаях лучше поглядеть на получившийся асм или попрофилировать

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.