[00:11:50] <valexey'> vlad2: я про кучу не понял
[00:12:20] <valexey'> что мешает инитить через тернарный оператор?
[00:12:50] <valexey'> A a = cond ? A(42) : A("hello");
[00:13:55] <vlad2> куча это окогда:
[00:13:58] <vlad2> X x* = NULL;
[00:14:08] <vlad2> if ( ... ) x = new X(...)
[00:14:54] <vlad2> Тернарый оператор не катит, потому что логика предусматривает непроиниченный случай.
[00:43:55] <valexey'> эмм... монаду Maybe отменили?
[00:44:10] <vlad2> В плюсах? :)
[00:45:10] <vlad2> Дык, я про то и говорю - признак "непроиниченности" должен быть отдельной сущностью, а не разруливаться в потрохах созданного объекта.
[00:45:25] <vlad2> Как этот признак выразить - другой вопрос.
[00:45:35] <vlad2> Нулевой указатель - простейший случай.
[00:45:49] <vlad2> boost::optional<> - C++ way
[01:08:02] <valexey'> vlad2: это что-то вроде такого: http://www.d-programming-language.org/phobos/std_typecons.html#Nullable ?
[01:13:17] <vlad2> Да.
[01:13:31] <vlad2> boost::optional<int> a;
[01:13:42] <vlad2> assert(!a);
[01:13:47] <vlad2> a = 5;
[01:13:55] <vlad2> assert(a);
[01:14:03] <vlad2> assert(a == 5);
[01:14:10] <vlad2> int b = *a;
[01:14:34] <valexey'> если не инициализировали a, но домогаемся до его, что будет? ассерт? исключение?
[01:15:03] <vlad2> По-моему там только в дебаге проверяется. С++ way ;)
[01:15:18] <valexey'> ub? :-)
[01:15:33] <vlad2> Вобщем да - это ошибка. Насчет диагностики не уверен. Вроде ub.
[01:16:26] <vlad2> типа "не платишь за то, чего не используешь". Хочешь проверку - сделай свой checked_optional.
[01:16:37] <valexey'> вот чтобы небыло такого, в хаскелях не просто тип Maybe используют, но заворачивают все это в монаду, которая не позволяет коду работать с неинициализированной какашкой.
[01:16:41] <valexey'> гарантированно.
[01:17:35] <vlad2> Ну в смысле - лепишь бросание исключения и получаешь такую же гарантию в плюсах.
[01:17:36] <valexey'> хотя это наверно на исключение похоже больше
[01:17:42] <valexey'> :-)
[01:17:43] <vlad2> Угу :)
[01:18:55] <valexey'> отсюда приходим к выводу, что исключение во всяких плюсах - это просто тупо одна из разновидностей монад :-) забавно.
[01:19:19] <valexey'> только без секса с типами когда монад становится больше одной.
[01:20:17] <vlad2>    reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
[01:20:33] <vlad2> Да, банальный ASSERT или ub в релизе
[01:22:49] <vlad2> Там есть интересный момент когда структура не копируемая.
[01:22:55] <vlad2> Как это в Ди решается?
[01:23:50] <valexey'> эмм... надо глянуть реализацию :-)
[01:24:03] <valexey'> а в плюсах как?
[01:24:06] <vlad2> Я имею ввиду когда конструктор копирования заппрещен.
[01:24:24] <vlad2> и оператор присваивания
[01:24:31] <valexey'> да, я понял
[01:24:56] <vlad2> оно разруливается с помощью boost::in_place
[01:25:27] <vlad2> Но для этого boost::optional должен быть заточен (знать) про boost::in_place
[01:25:58] <valexey'> а как этот бустинплейс выкручивается? в чем идея то?
[01:26:12] <vlad2> Там идея прстая на самом деле.
[01:26:57] <vlad2> class X { X(const X&); public: X(int); };
[01:27:08] <vlad2> boost::optional<X> x;
[01:27:23] <vlad2> x = boost::in_place( 3 );
[01:28:28] <vlad2> x = X(3); // не компилится
[01:28:33] <valexey'> гм. а как инплейс выкручивается?
[01:29:21] <vlad2> Он просто "упаковывает" аргументы. Так что экземпляр X создается только один - в самом boost::optional. Копирования/присваивания не требуется.
[01:30:11] <valexey'> эмм.. не понял :-)
[01:30:27] <vlad2> Очень удобно бывает для скоуп гардов (которые обычно как раз некопируемые) по условию.
[01:30:56] <vlad2> Ну где-то там унутрях boost::optional напсано такое:
[01:31:32] <vlad2> optional& operator = (const T& ); // обычный случай, когда T может быть скопирован
[01:32:20] <vlad2> optional& operator = (const in_place<T_args>& ); // спец. слцчай, когда T не может копироваться
[01:32:45] <valexey'> то есть он прямо in_place внутри себя хранит?
[01:32:49] <vlad2> Далее в какой-то момент:
[01:33:54] <vlad2> new (bytes_storage) T(unpack_in_place_args); // создание T в нужном куске памяти
[01:35:23] <valexey'> оу
[01:35:23] <vlad2> Не, оно его получает сверху и может вытащить нужные аргументы для создания T
[01:35:26] <valexey'> грязный хак!
[01:35:32] <valexey'> :-)
[01:35:40] <vlad2> Дык, вэлком ту С++ ;)
[01:36:10] <vlad2> ООП + мемори мэнэджмент до байтов :)
[01:36:25] <valexey'> хоть деструктор то у бывшего значения зовется?
[01:36:36] <vlad2> Дык!!! С++ же ш!
[01:36:41] <valexey'> а то эдак и утечь не долго
[01:37:12] <vlad2> Конечно там все вызывается. Нафиг оно было б нужно иначе.
[01:37:56] <vlad2> bytes_storage это массив как раз с размером sizeof(T)
[01:38:03] <valexey'> в принципе, ничто не мешает сделать также в D (если там нет более элегантного решения и если проблема эта там имеет место). Правда сборщик мусора может прифигеть немного :-)
[01:38:40] <valexey'> ну да ему не в первой - он консервативный пофигист :-)
[01:39:04] <vlad2> Да, я думал как мог бы optional выглядеть в других ЯП и пришел к выводу, что оно должно быть в языке :)
[01:39:11] <valexey'> vlad2: кстати, а какой смысл запрещать копирование, если любой завалящий чел может вот так вот хакнуть?
[01:40:19] <vlad2> Ну в смысле. Здесь хакнуто только то, что объект размещается в нетипизированном куске памяти. С сопутсвующими ручными вызовами деструктора. А так все по всем правилам.
[01:41:04] <valexey'> ну, кроме того, что мы обошли желание создателя этого класса :-)
[01:41:14] <valexey'> то есть желание чтобы низя было его копировать :-)
[01:41:47] <vlad2> В смысле обошли? Объект реально не копируется. Он создается. Я ж говорю - все работает с гардами.
[01:42:09] <vlad2> boost::optional<lock> optional_lock;
[01:42:27] <valexey'> с какими именно гардами?
[01:42:34] <vlad2> if (...) optional_lock = boost::in_place( critical_section );
[01:42:58] <valexey'> я знаю что формально он не копируется. он создается. но гм... какой в этом смысл собственно?
[01:43:10] <vlad2> В даноом примере критическая секция будет локнута по условию и лок будет в единственном экзэмпляре.
[01:43:13] <valexey'> точнее так - какой смысл запрещать копирование объекта?
[01:43:37] <vlad2> Ну а как ты сделаешь копирование вот такого лока?
[01:43:56] <vlad2> которые савит лок в конструкторе и снимает в деструктореэ
[01:44:11] <valexey'> optional_lock = boost::in_place( critical_section ); optional_lock = boost::in_place( critical_section );
[01:44:27] <valexey'> тут будет лок-разлок-лок?
[01:44:38] <vlad2> В данном случае лок снимется и снова поставится.
[01:44:41] <valexey'> то есть появится временная щщель :-)
[01:45:09] <vlad2> Но не будет рекурсивного лока (который не всегда возможен)
[01:45:10] <valexey'> а, я понял. нам нужен объект который оборачивает некую уникальную сущность
[01:45:19] <vlad2> Да.
[01:45:30] <valexey'> и чтобы никогда, НИКОГДА этой сущностью не рулили двое казлов
[01:45:36] <vlad2> Да.
[01:46:22] <valexey'> для этого в D есть такое: http://www.d-programming-language.org/phobos/std_typecons.html#Unique
[01:46:32] <valexey'> точнее в стандартной либе
[01:46:54] <vlad2> Это типа auto_ptr?
[01:48:11] <valexey'> похоже
[01:48:43] <vlad2> Имеет смысл только в присутствии деструкторов :)
[01:50:30] <valexey'> гм. а кто деструкторы в D отменял? :-)
[01:51:09] <valexey'> ~this() и вперед, с песнями
[01:53:12] <valexey'> а кстати, если у нас есть такой замечательный auto_ptr для уникальных сущностей, то зачем нам нужена в языке возможность прямого запрета копирования объектов некого класса?
[02:01:49] <valexey'> vlad2: покурил книжку по D. Ты не поверишь, но в данном случае копирования не будет :-)
[02:01:54] <valexey'> Будет перемещение объекта.
[02:02:10] <valexey'> По сути этот хак, с boost:in_place, вшит в язык.
[02:02:28] <valexey'> То есть не ради Nullable, а как одна из концептуальных фич
[02:02:50] <valexey'> компилятор анализирует это дело и если копия не нужна, её не будет.
[02:26:43] <valexey'> хотя похоже я наврал :-) концептуальный хак в языке есть, но он не про то.
[03:08:07] <vlad2> Тут важен момент гарантии :) Что вот в такой синтаксической форме копирования не будет.
[03:08:24] <vlad2> Потому как лишние копирования и в С++ "не запрещены"
[03:09:29] <vlad2> (точнее не запрещено оптимизировать лишние копирования даже если контруктор не пустой)
[03:43:24] <valexey'> угу. оно там есть.
[03:43:49] <valexey'> кстати, конструктор копирования там выпиливается не посредством запривачивания его, а посредством удаления/зануления
[03:43:55] <valexey'> this(this) = null;
[03:44:28] <valexey'> это принципиально, кстати. ибо приват не спас бы от копирования в этом же модуле
[03:51:30] <valexey'> А этот Unique смотрится в либе недопиленным.
[03:51:50] <valexey'> Похоже у народа еще руки не дошли его допилить (или компилятор еще не допилен до нужного состояния)