<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-654279083390275842</id><updated>2026-04-12T12:03:50.160+03:00</updated><category term="О программировании"/><category term="О жизни"/><category term="язык C++"/><category term="Поток сознания"/><category term="Foto"/><category term="Ссылки"/><category term="SObjectizer"/><category term="О работе"/><category term="Внушаить"/><category term="Мысля давеча посетила"/><category term="Кино"/><category term="Humour"/><category term="Спорт"/><category term="Дартс"/><category term="Павбывавбы"/><category term="Мои фото"/><category term="Подсмотренное"/><category term="Из непонятого"/><category term="Actor Model"/><category term="Маразм крепчал"/><category term="Multithreading"/><category term="Афигеть"/><category term="Об управлении"/><category term="Отдых"/><category term="Message-Passing"/><category term="Concurrency"/><category term="Bugs"/><category term="Вопрос залу"/><category term="Хвастаюсь"/><category term="Business"/><category term="Book review"/><category term="О компьютерах"/><category term="Знакомство с фотомастером"/><category term="Природа"/><category term="язык Ruby"/><category term="RESTinio"/><category term="Отлично сказано"/><category term="Mxx_ru"/><category term="Путешествия"/><category term="История"/><category term="Штуковина"/><category term="язык Java"/><category term="Воспоминания"/><category term="Parallel Programming"/><category term="Сиде-2012"/><category term="язык Scala"/><category term="язык Rust"/><category term="Блог"/><category term="язык D"/><category term="ACE"/><category term="Искусство"/><category term="язык Go"/><category term="Music"/><category term="Велосипедостроение"/><category term="язык C"/><category term="OpenSource"/><category term="Быть начальником?"/><category term="Отличная мысль"/><category term="CMake"/><category term="Каппадокия-2012"/><category term="Кризис в РБ"/><category term="Фантастика"/><category term="Могилев-2013-04"/><category term="Музыка"/><category term="Склерозник"/><category term="язык Erlang"/><category term="POCO"/><category term="Внезапно"/><category term="язык Haskell"/><category term="Живопись"/><category term="Функциональное программирование"/><category term="Boost"/><category term="MQTT"/><category term="timertt"/><category term="Книга &quot;Оружие победы&quot;"/><category term="Сиде-2011"/><category term="DDS"/><category term="Internet of Things"/><category term="ObjESSty"/><category term="Profileschool"/><category term="Книга &quot;Живая компания&quot;"/><category term="Книга &quot;Структура в кулаке&quot;"/><category term="Machine-2-Machine"/><category term="Must Read"/><category term="json_dto"/><category term="Книга &quot;В поисках совершенства&quot;"/><category term="Shrimp Demo-Project"/><category term="Война"/><category term="Язык Eiffel"/><category term="Akka"/><category term="Amazon&#39;s Dynamo"/><category term="ODBC"/><category term="VIM"/><category term="Библиотека OTL"/><category term="День Нептуна-2013"/><category term="Жестокость"/><category term="Лучше не скажешь"/><category term="Спиртное"/><category term="Характерный портрет"/><category term="AMQP"/><category term="Overloading Control"/><category term="Serialization"/><category term="XML"/><category term="ZeroMQ"/><category term="Книга &quot;Великие а не большие&quot;"/><category term="Книга &quot;Построенные навечно&quot;"/><category term="Погружение в Agile"/><category term="Успешные Менеджеры Программистов"/><category term="язык JavaScript"/><category term="язык OCaml"/><category term="Asio"/><category term="Carl Zeiss"/><category term="War"/><category term="gSOAP"/><category term="Эдвардс Деминг"/><category term="язык Ceylon"/><category term="&#xa;язык D#О программировании"/><category term="О жизни"/><category term="О работе#О программированииПоток сознания"/><category term="#О программированииязык Scala"/><category term="Benchmark"/><category term="Catch2"/><category term="GSM"/><category term="Kilim"/><category term="Kubuntu"/><category term="LaTeX"/><category term="MSSQL"/><category term="MinGW"/><category term="NoSQL"/><category term="OODB"/><category term="Qt"/><category term="SOAP"/><category term="SourceForge"/><category term="Unix"/><category term="doctest"/><category term="Боевик"/><category term="Генри Минцберг"/><category term="Дарс"/><category term="Книга &quot;Выход из кризиса&quot;"/><category term="Наука"/><category term="Рыбалка"/><category term="Старческое брюзжание"/><category term="язык Ada"/><category term="язык Gosu"/><category term="язык PHP"/><category term="язык Python"/><title type='text'>Размышлизмы eao197</title><subtitle type='html'>Размышления и впечатления, которые не хочется держать в себе. О программировании в частности. Ну и о творчестве, и о жизни вообще.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3794</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-2905440149949091685</id><published>2030-01-01T00:00:00.002+03:00</published><updated>2025-05-20T06:31:53.669+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Блог"/><title type='text'>О блоге</title><content type='html'>&lt;p&gt;Более тридцати лет я занимался разработкой ПО, в основном как программист и тим-лид, а в 2012-2014гг как руководитель департамента разработки и внедрения ПО в компании Интервэйл (подробнее на &lt;a href=&quot;http://www.linkedin.com/in/eao197/&quot;&gt;LinkedIn&lt;/a&gt;). В настоящее время занимаюсь развитием компании по разработке ПО &lt;a href=&quot;http://stiffstream.com&quot;&gt;&lt;b&gt;stiff&lt;/b&gt;stream&lt;/a&gt;, в которой являюсь одним из соучредителей. Поэтому в моем блоге много заметок &lt;a href=&quot;http://eao197.blogspot.com/search/label/%D0%9E%20%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%B5&quot;&gt;о работе&lt;/a&gt;, в частности &lt;a href=&quot;http://eao197.blogspot.com/search/label/%D0%9E%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B8&quot;&gt;о программировании&lt;/a&gt; и &lt;a href=&quot;http://eao197.blogspot.com/search/label/%D0%9E%20%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0%D1%85&quot;&gt;компьютерах&lt;/a&gt;, а так же &lt;a href=&quot;http://eao197.blogspot.com/search/label/%D0%9E%D0%B1%20%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B8&quot;&gt;об управлении&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Так же я пишу &lt;a href=&quot;http://eao197.blogspot.com/search/label/%D0%9E%20%D0%B6%D0%B8%D0%B7%D0%BD%D0%B8&quot;&gt;о жизни&lt;/a&gt; вообще и о нескольких своих увлечениях: &lt;a href=&quot;http://eao197.blogspot.com/search/label/Foto&quot;&gt;о фотографии&lt;/a&gt; (включая публикацию &lt;a href=&quot;http://eao197.blogspot.com/search/label/%D0%9C%D0%BE%D0%B8%20%D1%84%D0%BE%D1%82%D0%BE&quot;&gt;своих фотографий&lt;/a&gt;, некоторые есть и на &lt;a href=&quot;http://www.zeissimages.com/standardgallery.php?puid=2701&amp;showall&quot;&gt;ZeissImages&lt;/a&gt;), &lt;a href=&quot;http://eao197.blogspot.com/search/label/%D0%A1%D0%BF%D0%BE%D1%80%D1%82&quot;&gt;о спорте&lt;/a&gt;, особенно &lt;a href=&quot;http://eao197.blogspot.com/search/label/%D0%94%D0%B0%D1%80%D1%82%D1%81&quot;&gt;о дартсе&lt;/a&gt;, и, совсем коротко, &lt;a href=&quot;http://eao197.blogspot.com/search/label/%D0%9A%D0%B8%D0%BD%D0%BE&quot;&gt;о кино&lt;/a&gt;.&lt;/p&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2905440149949091685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2905440149949091685'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2014/05/blog-post.html' title='О блоге'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-2770562979760356223</id><published>2029-12-31T10:53:00.000+03:00</published><updated>2018-04-27T17:06:39.634+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Foto"/><category scheme="http://www.blogger.com/atom/ns#" term="Мои фото"/><category scheme="http://www.blogger.com/atom/ns#" term="О жизни"/><title type='text'>[life.photo] Характерный портрет: вы и ваш мир моими глазами. Безвозмездно :)</title><content type='html'>&lt;p&gt;Вы художник? Бармен или музыкант? Или, может быть, коллекционер? Плотник или столяр? Кузнец или слесарь? Владеете маленьким магазинчиком или управляете большим производством? Реставрируете старинные часы или просто починяете примус? Всю жизнь занимаетесь своим любимым делом и хотели бы иметь фото на память?&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOXzdoXx5jrFBn7G9z7Pz6GcTBgwYJysWvLXJw_fB415r9yK0jLTN0vRbSELrwto6HwKUM2GvlRv219Kl61hvnBRZYL8IN5Jp7siO0y0uxc__Kovaqgc7hjsk-jjJPmSdIQHSEgenkTOk/s800-Ic42/portrait_collage_20151001.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;Предлагаю сделать портрет в обстановке, связанной с вашей работой или увлечением. Абсолютно бесплатно. Очень уж мне нравится фотографировать людей в их естественной среде. Происходить это может так...&lt;/p&gt;

&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;

&lt;p&gt;...Вы делаете то, что умеете и любите, попутно рассказывая о себе и своей профессии/хобби. Я же становлюсь вашей тенью и/или собеседником, снимаю кадр за кадром в погоне за наиболее удачным снимком. Если что-то получается, то вам достаются фотографии в электронном виде, а мне -- возможность их некоммерческого использования в блоге и соцсетях.&lt;/p&gt;

&lt;p&gt;Если вы заинтересовались, то связаться со мной можно по мейлу eao197 на gmail точка com или в Skype по имени eao197. Либо же оставив комментарий к этой записи. Или в соцсетях: &lt;a href=&quot;http://vk.com/eao197&quot;&gt;VK&lt;/a&gt;, &lt;a href=&quot;https://www.facebook.com/eao197&quot;&gt;Facebook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Для съемки мне нужно знать в каких условиях будет проходить фотосессия: помещение или открытое пространство, темно там или светло, можно ли использовать вспышку или это будет невозможно в принципе и т.д. Если мое присутствие на вашем рабочем месте или рядом с ним требует какого-то предварительного согласования -- то вам самим нужно будет позаботиться об этом. Ну и было бы желательно, чтобы ваши коллеги и клиенты были в курсе и не протестовали бы против попадания в кадр.&lt;/p&gt;

&lt;p&gt;Во избежание чрезмерных ожиданий хочу сразу предупредить: я всего лишь любитель, не проффи. Поэтому результат не гарантирован. По опыту, для того, чтобы получился хороший портрет, приоткрывающий характер человека, нужен не один дубль, и даже не десять, а то и не сто. Ориентироваться нужно на 3-4 часа общения и фотосьемки, что выльется в несколько сотен кадров из которых будет отобрано всего несколько штук. Так что вам потребуется немного терпения, а мне -- капелька удачи.&lt;/p&gt;

&lt;p&gt;Вот пример того, что может получаться в результате таких съемок:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;кукольных дел мастер &lt;a href=&quot;https://goo.gl/photos/khfXG6kGQ52yELyu7&quot;&gt;Екатерина Katiedda Минакова&lt;/a&gt;;&lt;/li&gt;
  &lt;li&gt;саксофонист &lt;a href=&quot;https://goo.gl/photos/t2t7v58jgVRpN4Xr8&quot;&gt;Анатолий Аксёнов&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;резчик по дереву &lt;a href=&quot;https://plus.google.com/photos/117023091752061088817/albums/6178693720360830017&quot;&gt;Виктор Россолов&lt;/a&gt;;&lt;/li&gt;
  &lt;li&gt;уникальный гармонист &lt;a href=&quot;https://goo.gl/photos/k4PGyrA7MzYqf8Zu7&quot;&gt;Вячеслав Сивуха&lt;/a&gt;;&lt;/li&gt;
  &lt;li&gt;кузнец &lt;a href=&quot;https://goo.gl/photos/Zq9YH84PQjXCYpgG7&quot;&gt;Дмитрий Андреев&lt;/a&gt;;&lt;/li&gt;
  &lt;li&gt;реконструктор &lt;a href=&quot;https://goo.gl/photos/YF8vhEwEKfrPURo47&quot;&gt;Виталий Медведев&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Вот еще несколько примеров того, что получалось в прошлом:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhifcC-yjcJRTTk3s_e4rgb6kBJUGAT7gMbHZHzWz3Vb9h1sN_X8LamFz7DZ-2IlGrG-SUDbMWZMx7BNNV7nKErZ4n6IIckeT7r-j9jWRot-gVQgDApyNmgt_JB6n79fC-zE9bqNHJmtMpR/w1236-h824-no/20150412-144413-KLN_3957.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Танго на набережной --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggFi_ELwi-Tt6l_1o1E32y-_mgOgjLLzH0_dAxJfkXSl3s91P-pSSu9NqgSlnHzjvkidAAMUhB4XflmgKRBLWPcfIzWj1Pk2WL2Mx_smJ7_1ShOTFsTTxcb3R5NgVu1CPyAwSjrysbH9RR/w548-h823-no/20130719-200026-20130719-200026.jpg&quot; height=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- День нептуна --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXSeO_FWkX9vrWPNQTZqM7LhCsPkyJS6ARhRQGXG3-AcFBZrBhaqBYgzNOxZmsBqP7JzUSO7wpZOgTidaFMqk3MDbm9Z_o2vD0r9iQ1ASR4BGEntsWMJxhsV1QPchhU_ap-jTaTDPANp5h/w1398-h824-no/20130713-123844-20130713-123844.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- --&gt;

&lt;p&gt;&lt;img src=&quot;http://www.zeissimages.com/gallery/2701/U2701I1409694203.SEQ.0.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.zeissimages.com/gallery/2701/U2701I1402041657.SEQ.0.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.zeissimages.com/gallery/2701/U2701I1401782657.SEQ.0.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Сергей Вяхирев --&gt;

&lt;p&gt;&lt;img src=&quot;http://www.zeissimages.com/gallery/2701/U2701I1396898490.SEQ.0.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Скрипачка за столом --&gt;

&lt;p&gt;&lt;img src=&quot;http://www.zeissimages.com/gallery/2701/U2701I1394868675.SEQ.0.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Гитарист --&gt;

&lt;p&gt;&lt;img src=&quot;http://www.zeissimages.com/gallery/2701/U2701I1394868546.SEQ.0.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Коллекционер --&gt;

&lt;p&gt;&lt;img src=&quot;http://www.zeissimages.com/gallery/2701/U2701I1378559938.SEQ.0.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Музыканты в Минске под дождем --&gt;

&lt;p&gt;&lt;img src=&quot;http://www.zeissimages.com/gallery/2701/U2701I1377513249.SEQ.0.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Портрет фотографа --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ1QNGFkWrtHiOAgTtz5zFZJ3MJvTubJPSQX95FoRm-JD_X9CuegOkzXf4Z_1fkn8uBGEj5YSJGFG1Qo0j4I3qLqtWPVBrO2NFXh2006s56zasJjQjRL0Wr6d-lBO76WMY1RCRC70GKUg/w800-h532-no/20140302-141423.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Реконструкторы в Гомеле на Прудах в 2013-м --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT3NP_5J4-Mbu2ylqqUWg4WeWfU1Og-xhez2EF5RUUxGgPSQ9HyzJfuUvqvZkKNGz7F_r5pnmodFAcn6fcvizXMGe9sYJPAIf9en0mbIRLjN44aMTMWn1E6ifCVJxglSs3PqdtBo4ziIQ/w640-h800-no/20130703-174153.jpg&quot; height=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKur-Y7UIZqw3js9RB53-Ne-umQZuWL1wHSptbthka9hp0W6P77onZsuPdl0ioUfA18gzlB2mdVZ8j3bLiL7swCN0LEwn3Fre4MOVaUwhsbD6WdIpH0gP7K5UMBjSHcKusklCDVWc2UN8/w800-h532-no/20130703-171342.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- С первенства РБ по ката (кёкусинкай каратэ, 2015) --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE3a2H9DeTWkbKaDtbuNIhV9O3nS7QS1ACe5yKTjJKdMKwv7ZDual0cfWcgsSJQz1n-EQsIBWEYZ1Id8paEQDHMTTXnmmux1hCHAWPdpVnWdOZHH53XSVqqDuuIuEbEiBTpwRMEWYnv9A/w1238-h824-no/20150503-105021-KLN_4268.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgCHxrHcWhn769_p48SN0iZ4L12SV0P-9_o_QaB_bsv9vSi3U5-bCm-1__lDgwsXEFZLlKRMLPYKquIjzUjDu70q6xyrjSunJiaAzS4SVd9_ZdIkEXluHVNKd-l6BxRFmPKIPEKEL5OS8/w948-h824-no/20150503-113301-KLN_4471.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- С выступления рестлеров на 9-е мая 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhC20Dfr3WLZ9E5dR2cJEngLdTyQYJGMj_nJVUmJe4ZOB4544mlbtQNKlDJWP4cTbkbLxNrXVmwGOAPBRX5khJUVlPKRkqtrU_MF3QNL5IqdsEVussMcB0HAip1ZdnHcFGszOjxbOQENS8/w1238-h824-no/20150509-163040-KLN_5585.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Резчик по дереву Андрей Пастухов (9-е мая 2015) --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh91_sBu92Hln0lhoUEUmHPNeyCnTZIw5sIjsk_SYSkCbZ5NGob26lskCVVnRDcKuz64axtukTGPk2DQ5dYjx6kmCW1lRUfbRk1dvoJgyrLMqGAb85UjeTIdxTe11GXWaJ0GFIbcryPoXI/w548-h823-no/20150509-115629-KLN_5343.jpg&quot; height=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Пожилой коллекционер на 9-е мая 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCq5JemgTpg-GL1l9ST4UDAqDsSNt_yLCNb53DoqIJ23F8dIZ6cNjbE4I4rxsMlYGbCxsVW4HmgM6hCMRzZlzzVqOwltr6GDawimlvDDBa4l04ApI_7NXQim2YpTw3ym-57qdE5d0WqLI/w548-h823-no/20150509-123258-KLN_5434.jpg&quot; height=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Саксофонист Анатолий Аксёнов 31-го мая 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKUpmfVGkbT9B37uSVCDNZA3bzvzM8pnjB2JBSoUZNzDzuFuxAEY7OxLmnNy9PyunOWZy1NPfzz4d9SkSaqqiEkayrHHcm0PToKHmiyhc8gvx85MsSb8D9Unf2eMnjRsfT7pGM-dDkBbE/w1374-h914-no/&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Гончар со свистулькой в гомельском парке 31-го мая 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKc7wPx23qIvV0VhcDK8xMvnddQMP0WbrVIqLzPQoWzAyKaCvMVs1Hml6kz4nzCTFcWp_76ApLrEnInbTfL4KLatoE-R_so-Vn4V1AnSWiuAzeQU7JphHCWL0CPwKX8unvCKHAEqGzzlM/w1143-h914-no/&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Клоун на акции &quot;День красного носа&quot; 31-го мая 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyuVhUBIY1qjyRFW-IMEUj-qkMzCMF1DQ0xyYhv9cUGhI6XVrat88zYeHx9QD1dEBeANusq9fnQeoqZokj_XHbKAVWjb76Q7oCinspcbwvB-KlEqzSPKeb8Nisse2x_-7NiBrnh-Suffk/w1458-h914-no/&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Екатерина Минакова на мастерклассе по изготовлению кукол-тыквоголовок 20 июня 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-cAXLjAfasIZtlsztbKlUBbBzKyYH6BU5uV8eehc36cykLclz0uBLJrgmi1JtFyqgJZ6IZQnQ24-f40jb6tMLZUZ9BcN4gg-zaCMSFeRn6HBdwo39oEmFl4KgPkKsPd98BVVL4bqO6jo/w800/&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Два музыканта у ГЦК 24-го июня 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF_1hnFeYw2yKc2DnVJjy1J0hsVG84mKB3RwPO_bfXxS1S8kpvdtkCf1ZLfwBUFJ6XG76UkgCMXQE0R4FRUeq4iugRbVsEhG_Au9NQafUNE-9SKp-UWEdim9gENkYsqe2cXOHEEDtyCHQ/w800/&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5rZhlDaCdtFPK-iEN1g5_hQHWZNmbWpo3YNXYFdt9P9-yT1WmZu34gHWtpXUyyWAZC-jm7jS3Rw7LfHLtbaSSR_4UWhmgIu1xxP321EwnaeT_TWQXu2ksQFviImwb39UPlLDD07MLotI/w800/&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Виктор Россолов, резчик по дереву --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGMq55RIQknA7mKBSGVr4jhUUBV-t18hw9BzaDXzfpNuIcUPImXz_TY_hyphenhypheniPeKY3NCmUVGzJgbHqevMJgykdVb9i6BbE_rrqBNX0_N3zEPaxsl0XbBBZihz7hiteaRyGSnL_LUWsaHLJs/h800/&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMDaKKX2jHWf3Y6hjab0toitpjjgR7PAmzLiyMSeolf7dq2WlJ4Ig8d0h-pIUS8txw59dura-Ykg_Pe_KD_eovPtWzoxuMNfxtvQfPWXWQZpg54QDhaKVeX2d4y7WNgldwWWmBp8iTxi0/h800/&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0nAX9EHANBxYjNCGn372IbgjgfxT8puIaOS80TreWgWC6bDqa-sLLdPONk9s2G1C5IG2VKci7xw2GFoDRfCsAfW3G3vprdFMvcHlV7A0_gFfhl2X-FSo0SOYHAk_8Xw4OYWGmA4av7T4/w800/&quot;/&gt;&lt;/p&gt;

&lt;!-- Рыбак на соревнования по ловле рыбы фидером 2-го августа 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_Fz7t4qq1Sq6f2uRrAsONMzNmaO9xKFMLdd8tEiR8I5RhiFyMoJRB3qVNwJHIK8Q91bHAiaXFInpBvE-LvD1xXlZM5qiYKES9g5SkDtdaYBeZL0hokXKUbUrW946w_K6dbkka2ot2ZTU/w800/&quot;/&gt;&lt;/p&gt;

&lt;!-- Вячеслав Сивуха 29-го августа 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrT-u70zu5ct3AJGIGHNDkfuD2EeOgRD2a0UQWH_EfonOsLZje58ROKSIRFDCJ_LufKdRwfAZS8xilb3YPEjI2TD7XQo8Q3Z7E2c3USMcDXZFq_vRl6ku4CF42Wk_DqyP5B_74aTi-dAY/w800/&quot;/&gt;&lt;/p&gt;

&lt;!-- С фестиваля &quot;Минск Старажытны&quot; 12-го сентября 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4GrXCz0bPTJnbZgzsPh3homr0BwdCNq2-DqmJ7GQnSZ90e9fTaCnul5q2b7fgJ961_ls5EHZg-jJzBo4b7yrIgcrB1TScScB8LIl7Cj8OYkYQ4itZBh2NfeBojKDGS3UWX8bB9L38oWQ/s800-Ic42/20150912-151417-DSC_0882.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvDCy81e4YysNurf-0h4nFbKb2GjzVjcFVdZFCQ-Whr8wovwkVWxFK_5nu-707hJKfuu04TQptRsZYAiPfyDf6DBAdDKmG5A1yJ2QwbcSDVHBLQOQikr8X6gb6E2x5LH9OrVmER8rBYZ4/s800-Ic42/20150912-152641-DSC_0925.jpg&quot;/&gt;&lt;/p&gt;

&lt;!-- Кузнец Дмитрий Андреев (23-е сентября 2015) --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRvCyJViaygimCzZR16fUzHSBR2cCM3KUuUrf0d7P9q2zRNkvTvrLRjHSf1N5lVwLuHY1mQ-jtfGBQOSksCk2vUAY-eg4qdUlMCUMqzEslHDvV-LoCREHsZV95VbxgH2k_sM6ugTpw01E/s800-Ic42/20150923-123159-DSC_1473.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_gfleps0XNHwnhj09nDaVGyFEUBHthLYG0IHJpRKaO4WdQrryU4Gt1A79-mLt62QZOxVNMFJ5pMc23xEU2xAJGNK_V2ILa8Es2o10QcD52on86QzEdnckpKWZ_uIeXcZ47XYj-KYuskU/s800-Ic42/20150923-130645-DSC_1628.jpg&quot;/&gt;&lt;/p&gt;

&lt;!-- Реконструктор Виталий Медведев (9-е мая 2016) --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDr5QOogMAu7h-24LVKoW6URZlnr425_uWTx84T_xZt11dMx90o-rDzk9op9LCQXyeECUxOgWPFNPqohad4gBq4Dzg1vHTWhglXErpbFEzaTKH6JxYguNU_fKZz-ZaRcR5WEzbkIk7bgw/s800/20160509-140603-DSC_6134.jpg&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgITCbq_SB_JDVejEOSMFd-JM6ZGvWi4xAxNqioyQDLWiUxg51nXeZTqn_FUIfOAmzvEKe073rsqsnqxKLxE9N6Cirfg6Zw6o3HkqJhg1Zes75ka0vV_O0vOUKTWcu8JVT6qn2yFKCuO7o/s800/20160509-141604-DSC_6195-2.jpg&quot;/&gt;&lt;/p&gt;

&lt;!-- Бородач за компьютером на CoreHard Spring 2017 (13-е мая 2017)) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/34349688134/in/photostream/&quot; title=&quot;20170513-112141-DSC_7774&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/5/4277/34349688134_2621e0ef2b_c.jpg&quot; width=&quot;800&quot; height=&quot;534&quot; alt=&quot;20170513-112141-DSC_7774&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;!-- Дори Экстерман на CoreHard Spring 2017 (13-е мая 2017)) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/34349687964/in/photostream/&quot; title=&quot;20170513-120348-DSC_7816&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/5/4274/34349687964_ef67a1b270_c.jpg&quot; width=&quot;800&quot; height=&quot;534&quot; alt=&quot;20170513-120348-DSC_7816&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;!-- ДиДжей на Фестивале городской еды (27-е августа 2017) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/36910824456/in/dateposted/&quot; title=&quot;20170827-142946-DSC_9303&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4377/36910824456_4a02bc95a5_c.jpg&quot; width=&quot;534&quot; height=&quot;800&quot; alt=&quot;20170827-142946-DSC_9303&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;!-- Жонглер на Дне Красного носа (27-е августа 2017) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/36957765561/in/photostream/&quot; title=&quot;20170827-134632-DSC_9214&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4346/36957765561_689280daeb_c.jpg&quot; width=&quot;534&quot; height=&quot;800&quot; alt=&quot;20170827-134632-DSC_9214&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;!-- Клоун на мотоцикле на Дне Красного носа (27-е августа 2017) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/37099333605/in/photostream/&quot; title=&quot;20170827-131334-DSC_9010&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4375/37099333605_dce23edd09_c.jpg&quot; width=&quot;800&quot; height=&quot;534&quot; alt=&quot;20170827-131334-DSC_9010&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;!-- Скрипач на Невском в Питере (апрель 2018) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/27868900178/in/dateposted/&quot; title=&quot;20180422-155704-DSCF0015&quot;&gt;&lt;img src=&quot;https://farm1.staticflickr.com/912/27868900178_ceeabf5305_c.jpg&quot; width=&quot;800&quot; height=&quot;533&quot; alt=&quot;20180422-155704-DSCF0015&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;!-- Гитарный мастер Евгений в Питере (апрель 2018) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/26800424547/in/photostream/&quot; title=&quot;20180422-143118-DSCF9903&quot;&gt;&lt;img src=&quot;https://farm1.staticflickr.com/825/26800424547_cede9a2743_c.jpg&quot; width=&quot;800&quot; height=&quot;533&quot; alt=&quot;20180422-143118-DSCF9903&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;p&gt;А можно отнестись к этой затее и более широко. Не обязательно иметь экзотическую профессию или уникальное хобби. Достаточно быть неординарным человеком и быть готовым провести несколько часов под прицелом фотоаппарта, желательно в подходящем антураже...&lt;/p&gt;

&lt;!-- Девушка из Танго на набережной --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLZ6yiBD4483bYfWnvrGBy3OXRqyEwkO2eSvhpGmF-rXTn5RCNNycMd9GVuW_0mfNpt1S7cUazdeQm7p1xQNnW9TbdZmeo5_RqgZfgdeL45CCwCTnyv-o1f5BCdNyER53aK2-lmEc-cX0I/w1238-h824-no/20130719-195618-20130719-195618.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Лёша Юша в Минске --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipDa7WAOebKiuNEAeJkkBfryC2LZ4BzAjRI7bwKqcO8f4Zma89qMnrlbkbX1YR2RaTsmfCbZAWEN1U4gOQHqd_hLbD7jb44dhcWCMqjuBpgePi8Oz8495R2tXyUMPiQli9233_OYngRJw/w800-h569-no/20131215-114227.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Андрей Тарасенко на Belarus Open --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1_kdV4N5wWkEaOlL-ipso65N57CfWXJg2Huo-qpamYMYJ0wGVUtu-LUHlPqVeToiDpnA1DahqY9l3Cp5zRdm9j5SpklDqdLxcznr-duoR2R45-eTEfZD6lNzXa1iljRiIhtYZVcxHLU4/w800-h532-no/20130824-201046.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiO0MNULOvLkhXM_yE8t-x5KNvUKuXrPPcsh5oLRT5RBPSm3WoHF2YRXKgdwD9PcwlO10YIWzl6pLQCwE5F_fgSLHu_o0lgCNnckYeY5_Y-CR52PB-2LjZ9K3rm5NrQath4lB_E1MbMDEE/w800-h532-no/20140504-203526.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.zeissimages.com/gallery/2701/U2701I1420460994.SEQ.0.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtyd8XUzToyw2hFKQjHuStquKmK6TgiN9pPjT_oajIEZtqDXh2LJWFnMA8oNBKqZr3I258JxibKqhRzIUOpy0WdCKMYv3_UbILLm1F2olymQG906Z-L1b83lxQMQA_ZKdKYrBZmsf6qftb/w800-h640-no/20131215-082410.jpg&quot; width=&quot;800&quot;/&gt;&lt;/p&gt;

&lt;!-- Алексей Голубев 1-го сентября 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZjUgHdf8cV_1MOpQ2KiMdtNWlEIqfKzo2TPn7f0hQLdIaNblQvfiozDWZ2P_1olUKYVN45RXMckjIzeihvE7kdpviUmDCW4l1FP2DOal-F_jZ9BPJdDfmLrJcZY_Lsr9z6FhehGJgtkg/w800/&quot;/&gt;&lt;/p&gt;

&lt;!-- Девушка играет на свистульке. Минск Старажытны, 12-го сентябры 2015 --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIQPL058wfGCdzrKqSUrsL3Gi-C0L7F8mIJzgiw2CZ8HXt_sCreAywMCPQCcZz_-EdYA8_d2HF3sViWJLyRVRLtBjUyB9sXr0zsXjEFG_WaoxAceFuwxZWB5HU5abLPa5w2I5qk5N9_0Q/s800-Ic42/20150912-144846-DSC_0820-2.jpg&quot;/&gt;&lt;/p&gt;

&lt;!-- Алексей Юша (Минск Старажытны, 12-го сентября 2015) --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsbqLqASBIlzY4F-drzVLaD2_P8U3APefX5_jQST1m5h6kHMsIVvisZLoGMUG_UhhDcLnL0StuusP2aAPAHg5hfcEXdbjVMmN6HU0ruH5truTxawOf4MQABpkHIh_a9smRUx315z_L5gA/s800-Ic42/20150912-125946-DSC_0471.jpg&quot;/&gt;&lt;/p&gt;

&lt;!-- Владислав Волков (Москва, 9-е февраля 2016) --&gt;

&lt;p&gt;&lt;img src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvMXbkjzlRN6V9g5vvKwPtYupIhvyT6iMkJtW8tXW-GBZMQCrMs_YTdOLRoR1ruXLYPA-i6avsoL5p1FOEr3fnf7PBfdsWcAf4OZ-C1aDxmQEPjFGlFiUKCVXYpA7xY3YTZIqrUKxGpHw/s800-Ic42/20160209-124944-DSCF2643.jpg&quot;/&gt;&lt;/p&gt;

&lt;!-- Коля Шмаков на CoreHard Spring 2017 (13-е мая 2017)) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/34349688574/in/dateposted/&quot; title=&quot;20170513-103826-DSC_7656&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/5/4290/34349688574_d1b88f8f08_c.jpg&quot; width=&quot;800&quot; height=&quot;534&quot; alt=&quot;20170513-103826-DSC_7656&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;!-- Ретро-фотограф на Дне Города (16-е сентября 2017) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/36447681394/in/dateposted/&quot; title=&quot;20170916-142459-DSC_9446&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4408/36447681394_1c98df6081_c.jpg&quot; width=&quot;800&quot; height=&quot;534&quot; alt=&quot;20170916-142459-DSC_9446&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;

&lt;!-- Музыканты на Дне Города (16-е сентября 2017) --&gt;

&lt;a data-flickr-embed=&quot;true&quot;  href=&quot;https://www.flickr.com/photos/152498119@N03/36887823000/in/photostream/&quot; title=&quot;20170916-154013-DSC_9543&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4331/36887823000_2d451b3b7a_c.jpg&quot; width=&quot;800&quot; height=&quot;534&quot; alt=&quot;20170916-154013-DSC_9543&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/2770562979760356223/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/2770562979760356223' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2770562979760356223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2770562979760356223'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2015/04/lifephoto_19.html' title='[life.photo] Характерный портрет: вы и ваш мир моими глазами. Безвозмездно :)'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOXzdoXx5jrFBn7G9z7Pz6GcTBgwYJysWvLXJw_fB415r9yK0jLTN0vRbSELrwto6HwKUM2GvlRv219Kl61hvnBRZYL8IN5Jp7siO0y0uxc__Kovaqgc7hjsk-jjJPmSdIQHSEgenkTOk/s72-c-Ic42/portrait_collage_20151001.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-6657736494222260054</id><published>2026-04-03T14:04:00.000+03:00</published><updated>2026-04-03T14:04:06.032+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Multithreading"/><category scheme="http://www.blogger.com/atom/ns#" term="SObjectizer"/><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Эх, давно я не брал в руки SObjectizer...</title><content type='html'>&lt;p&gt;Недавно в проекте у клиента наткнулись на &lt;a href=&quot;https://github.com/microsoft/mimalloc/issues/1250&quot;&gt;странное поведение mimalloc-а в одном из многопоточных сценариев использования&lt;/a&gt;. Дабы исключить фактор собственных ошибок понадобилось сделать минимальный пример, на котором это странное поведение воспроизводится. Ну и чтобы пример был минималистичным, то пришлось воспользоваться только тем, что есть в стандартной библиотеке C++ &quot;из коробки&quot;.&lt;/p&gt;

&lt;p&gt;Получилось &lt;a href=&quot;https://github.com/eao197/mimalloc_vcpkg_20260331/blob/675f07e974d6af599f6c7dc0da1105718b556ade/main.cpp#L88-L187&quot;&gt;ну такое себе&lt;/a&gt;. Вроде бы и ничего сложного, но корявенько. Плюс писалось все это неожиданного долго, думал, что минут за 15 накидаю, но в итоге ушло минут сорок.&lt;/p&gt;

&lt;p&gt;Хотя казалось бы: всего-то нужно запустить дочернюю нить, которая бы получала от родительской нити указатель на memory_pool, после чего использовала бы этот пул какое-то время, затем уведомляла бы родительскую нить о том, что все действия с пулом сделаны, после чего ждала бы следующий memory_pool или уведомление о завершении работы.&lt;/p&gt;

&lt;p&gt;Передачу memory_pool-а в дочернюю нить сделал через переменные, защищенные mutex-ом. А чтобы эффективно ждать появление значений в этих переменных -- std::condition_variable. Чтобы получить уведомление от дочерней нити о том, что memory_pool перестал использоваться, задействуется std::promise и std::future. Как-то многовато для того, чтобы прокинуть одну команду из родительской нити в дочернюю, а затем один сигнал обратно 🙁&lt;/p&gt;

&lt;p&gt;Да еще и без ошибок не обошлось, изначально не сбрасывались указатели на значения, которые забирались дочерней нитью из главной нити. Из-за чего дочерняя нить могла уйти на следующую итерацию имея на руках уже недействительные указатели. Поэтому пришлось дополнить дочернюю нить небольшим, но очень важным &lt;a href=&quot;https://github.com/eao197/mimalloc_vcpkg_20260331/blob/675f07e974d6af599f6c7dc0da1105718b556ade/main.cpp#L131-L134&quot;&gt;блоком&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;И вот после того, как все это было сделано, стала терзать мысль о том, что на SObjectizer-е с mchain-ами должно же было бы получиться проще. Терзала она меня, терзала, и в конце-концов заставила потратить немного времени, чтобы сделать &lt;a href=&quot;https://github.com/eao197/mimalloc_so5_vcpkg_20260403/blob/2001ee0111dc06645fdfafb5451564f0fc925780/main.cpp#L84-L166&quot;&gt;вариант на SO-5&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ну и что хочу сказать? 😉&lt;/p&gt;

&lt;p&gt;На SO-5 и компактнее, и проще, и понятнее. На мой сугубо субъективный взгляд.&lt;/p&gt;

&lt;p&gt;Всего-то создается два канала (mchain-а): один для передачи информации из родительской нити в дочернюю, второй для уведомлений в обратном направлении. Когда родительская нить подготавливает новый memory_pool, то указатель на него отсылается в канал для дочерней нити простым сообщением. Когда дочерняя нить хочет уведомить о том, что работа с memory_pool завершена, то отсылается еще более простой сигнал во второй канал.&lt;/p&gt;

&lt;p&gt;Получается тривиальное взаимодействие: в родительской нити &lt;a href=&quot;https://github.com/eao197/mimalloc_so5_vcpkg_20260403/blob/2001ee0111dc06645fdfafb5451564f0fc925780/main.cpp#L147-L153&quot;&gt;сперва send, затем receive&lt;/a&gt;, а в дочерней нити &lt;a href=&quot;https://github.com/eao197/mimalloc_so5_vcpkg_20260403/blob/2001ee0111dc06645fdfafb5451564f0fc925780/main.cpp#L111-L131&quot;&gt;сперва receive из которого уже делается send в обратном направлении&lt;/a&gt;.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Отдельный вопрос по поводу надежности каждого из решений. В общем, она там везде никакая, т.к. изначально все рассчитано только на happy path.&lt;/p&gt;

&lt;p&gt;Однако, если встанет вопрос о том, чтобы гарантировать завершение дочерней нити если где-то в главной возникнет исключение... Или чтобы мы контролировали максимальное время ожидания информации... То, имхо, с вариантом на SObjectizer-е будет проще:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;автоматическое завершение дочерней нити в SObjectizer-варианте как раз уже обеспечивается &lt;a href=&quot;https://github.com/eao197/mimalloc_so5_vcpkg_20260403/blob/2001ee0111dc06645fdfafb5451564f0fc925780/main.cpp#L134-L140&quot;&gt;за счет использования auto_joiner-ов и auto_closer-ов&lt;/a&gt;;&lt;/li&gt;
  &lt;li&gt;контроль тайм-аутов ожидания в случае с so_5::receive добавляется элементарно. В случае с примитивами из C++ной библиотеки, в принципе, тоже не сложно, но телодвижений, имхо, все-таки чуть-чуть побольше потребуется.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr/&gt;

&lt;p&gt;Я специально не стал вставлять фрагменты кода в пост, а дал ссылки на github. Прежде всего ради экономии собственного времени на написание этого текста. Но если такой вариант неудобен и читателям хотелось бы видеть куски кода прямо здесь, то дайте знать в комментариях, пожалуйста.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/6657736494222260054/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/6657736494222260054' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/6657736494222260054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/6657736494222260054'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/04/progc-sobjectizer.html' title='[prog.c++] Эх, давно я не брал в руки SObjectizer...'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-1309215224237526802</id><published>2026-04-02T07:47:00.001+03:00</published><updated>2026-04-02T07:47:51.406+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Кино"/><category scheme="http://www.blogger.com/atom/ns#" term="О жизни"/><category scheme="http://www.blogger.com/atom/ns#" term="Ссылки"/><title type='text'>[life.cinema] Очередной кинообзор (2026/03)</title><content type='html'>&lt;p&gt;Традиционный отчет о просмотренных за минувший месяц фильмах. Традиционно в начале каждого из списков то, что понравилось больше. А в конце то, что спокойно можно проигнорировать.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Фильмы&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/106203/annot/&quot;&gt;Аватар: Огонь и пепел (Avatar: Fire and Ash, 2025)&lt;/a&gt;. Лично мне понравился гораздо больше, чем вторая часть. Ничем не удивил, но это образец отлично сделанного аттракциона, после которого не жалко потраченного времени.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/203212/annot/&quot;&gt;Ограбление в Лос-Анджелесе (Crime 101, 2026)&lt;/a&gt;. В принципе, норм. Но мне не хватило экшена и показалось, что фильм излишне затянут.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/206119/annot/&quot;&gt;Военная машина (War Machine, 2026)&lt;/a&gt;. Красочно, динамично, прямолинейно, тупо и пафосно. При желании можно посмотреть, а можно и проигнорировать данное &quot;кино&quot;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/182540/annot/&quot;&gt;Ночной замес (Wake Up, 2023)&lt;/a&gt;. Хороший пример недорогого молодежного слешера. Любители жанра могут спокойно смотреть, здесь нет ничего лишнего, мне даже понравилось как сыграл главный злодей.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/202907/annot/&quot;&gt;На помощь! (Send Help, 2026)&lt;/a&gt;. Не понял что это было: для серьезного триллера слишком много дурацкого юмора и откровенного треша, для чернушной треш-комедии слишком мало дурацкого юмора и откровенного треша. Как сюда занесло Рейчел МакАдамс просто загадка.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/203591/annot/&quot;&gt;Крик 7 (Scream 7, 2026)&lt;/a&gt;. Динамично, кроваво. Но тупость большинства персонажей множит все хорошее на ноль.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/205952/annot/&quot;&gt;Адское пламя (Hellfire, 2026)&lt;/a&gt;. Мог бы быть душевный боевичок в стиле 1980-х с сильно постаревшими, но крутыми в прошлом актерами, если бы не нарисованная на компьютере стрельба. Такая откровенная дешевизна убивает все хорошее, что в фильме могло бы быть. Можно смело пройти мимо и не тратить свое время.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/ros/190931/annot/&quot;&gt;Тропа гнева (2025)&lt;/a&gt;. Откровенная халтура, лучше не смотреть.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/206952/annot/&quot;&gt;Иерархия (Hierarchy, 2025)&lt;/a&gt;. Дешевая поделка. Не стоит тратить на это время.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Сериалы&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/ros/173162/annot/&quot;&gt;Подслушано в Рыбинске (первый сезон, 2024)&lt;/a&gt;. Отличное кино, посмотрел с удовольствием.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/205801/annot/&quot;&gt;Ограбление (Steal, первый сезон, 2025)&lt;/a&gt;. Нормально. Есть пара моментов, к которым мне бы хотелось придраться, но в целом можно смотреть.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/ros/161670/annot/&quot;&gt;Теория больших денег (первый сезон, 2023)&lt;/a&gt;. Поначалу производит впечатление веселой криминальной комедии. Но затем появляется столько трупов, что веселой комедией происходящее быть перестает. При этом на реально черную комедию, для которой такое количество жертв было бы уместно, сериал не тянет, увы. Поэтому оставляет сильно двойственное впечатление. Посмотреть, тем не менее, можно. Не шедевр, но скоротать три-четыре вечера можно.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/169321/annot/&quot;&gt;Захваченный рейс (Hijack, второй сезон, 2026)&lt;/a&gt;. К сожалению, можно лишь повторить то, что писал про первый сезон: &quot;Отлично снято и к игре актеров нет претензий. Пожалуй, это все хорошее, что можно сказать про этот сериал. Остальное, как по мне, одни недостатки.&quot; Если кому-то понравился первый сезон, то можно глянуть и второй. А вот если не понравился или не смотрели, то лучше бы пройти мимо.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/euro/162916/annot/&quot;&gt;Незнакомка (The Stranger, 2020)&lt;/a&gt;. Смотреть интересно, но когда сезон заканчивается и начинаешь анализировать итоги, то складывается ощущение, что &quot;нам втирали какую-то дичь&quot;.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/1309215224237526802/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/1309215224237526802' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/1309215224237526802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/1309215224237526802'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/04/lifecinema-202603.html' title='[life.cinema] Очередной кинообзор (2026/03)'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-7625055124871475443</id><published>2026-03-30T18:45:00.000+03:00</published><updated>2026-03-30T18:45:55.956+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Говорят, что основная работа над C++26 завершена</title><content type='html'>&lt;p&gt;Например, об этом &lt;a href=&quot;https://herbsutter.com/2026/03/29/c26-is-done-trip-report-march-2026-iso-c-standards-meeting-london-croydon-uk/&quot;&gt;написал Герб Саттер&lt;/a&gt;. Типа в C++ теперь есть и рефлексия, и контракты, и даже уменьшено число UB. Уж теперь-то точно заживем.&lt;/p&gt;

&lt;p&gt;У меня, однако, отношение к данному событию весьма равнодушное.&lt;/p&gt;

&lt;p&gt;Ну вот не отношусь к счастливчикам, которые пилят один проект для одной платформы на одном компиляторе. Посему не могу сидеть на самом свежем GCC (или clang-е, или MSVC) под самой-самой свежей ОС и наслаждаться плюшками самого свежего C++. До меня эти нововведения доходят спустя годы. Так что если смогу задействовать C++26 в продакшене году эдак в 2029-ом, то и хорошо.&lt;/p&gt;

&lt;p&gt;Кроме того, в современный C++ завозят, вроде бы, крайне полезные вещи, но в таком виде, что оторопь берет.&lt;/p&gt;

&lt;p&gt;Например, синтаксис для рефлексии. Повторял, повторю и буду повторять, что сочетания &lt;tt&gt;[:&lt;/tt&gt; и &lt;tt&gt;:]&lt;/tt&gt; -- это, наверное, худшее из того, что можно было придумать. Настолько плохо это различимо в коде, что просто караул.&lt;/p&gt;

&lt;p&gt;Ну или взять контракты. В Eiffel-е -- это одна из самых классных фич языка, можно сказать киллер-фича. Тогда как в C++26 я что-то не вижу возможности использования &lt;tt&gt;old&lt;/tt&gt; в постусловиях. Такое ощущение, что в C++ных контрактах мне не получится написать что-то вроде:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;void push_back(T v) post(this-&gt;size() == old this-&gt;size() + 1)
{...}&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;Если я ошибаюсь, то буду признателен за подсказку о том, как такой фокус в C++ных контрактах осуществить.&lt;/p&gt;

&lt;p&gt;В общем, для кого-то C++ в очередной раз стал лучше. Но пока что не для меня, т.к. моя основная рабочая лошадка -- это C++17 и, местами, C++20. Однако тех, кому нововведения в C++26 нравятся и кто сможет начать их применять в ближайшее время, можно поздравить.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/7625055124871475443/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/7625055124871475443' title='Комментарии: 2'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/7625055124871475443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/7625055124871475443'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/03/progc-c26.html' title='[prog.c++] Говорят, что основная работа над C++26 завершена'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-3666370001388055947</id><published>2026-03-09T13:15:00.000+03:00</published><updated>2026-03-09T13:15:25.622+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Из непонятого"/><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Как будто бы недоделки в системе C++ных аллокаторов</title><content type='html'>&lt;p&gt;Потратил некоторое время на адаптацию хитрого контейнера под аллокаторы. В процессе адаптации столкнулся с несколькими вещами, которые выглядят как недоделки. Как будто бы до них просто руки не дошли. Ну или я просто чего-то полезного не нашел.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Первая штука -- это отсутствие каких-то простых инструментов для создания нового объекта посредством аллокатора.&lt;/p&gt;

&lt;p&gt;Если нам не нужно связываться с аллокаторами, то мы просто вызываем new T (или make_unique&amp;lt;T&amp;gt; или make_shared&amp;lt;T&amp;gt;) и все.&lt;/p&gt;

&lt;p&gt;А вот в случае с аллокаторами сперва нужно вызвать у аллокатора allocate чтобы получить блок памяти под объект. А затем нужно вызывать у аллокатора construct, чтобы сконструировать объект в этом блоке. Т.е. два действия вместо одного. При этом, если construct бросает исключение, то нужно вручную освободить блок памяти посредством обращения к deallocate у аллокатора.&lt;/p&gt;

&lt;p&gt;Но вот простого метода, который бы сперва сам вызвал allocate и следом construct, в стандартной библиотеке я не нашел. Есть там &lt;a href=&quot;https://en.cppreference.com/w/cpp/memory/make_obj_using_allocator.html&quot;&gt;make_obj_using_allocator&lt;/a&gt;, но он вроде как для совсем другого.&lt;/p&gt;

&lt;p&gt;Так же нет простого метода, который бы взял ссылку на аллокатор и указатель на удаляемый объект и сам бы сперва вызвал destroy для объекта, а потом deallocate для блока памяти. А хотелось бы иметь готовый, а не делать самостоятельно на коленке.&lt;/p&gt;

&lt;p&gt;И да, я знаю, что allocate/construct и destroy/deallocate вызываются через allocator_traits, просто не упоминаю об этом для простоты изложения.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;В C++17 в стандартную библиотеку добавили &lt;a href=&quot;https://en.cppreference.com/w/cpp/memory/memory_resource.html&quot;&gt;std::pmr::memory_resource&lt;/a&gt;. И, вроде как, имеет смысл делать свои арены в виде наследников от memory_resource.&lt;/p&gt;

&lt;p&gt;Но, как я понял, дизайн memory_resource направлен на то, чтобы информировать о возникающих ошибках только через выброс исключения. Поскольку метод &lt;a href=&quot;https://en.cppreference.com/w/cpp/memory/memory_resource/do_allocate.html&quot;&gt;do_allocate&lt;/a&gt; должен бросать исключение при невозможности выделить память.&lt;/p&gt;

&lt;p&gt;И тут вопрос: а как быть, если мы не хотим получать исключение? Например, нам хотелось бы иметь аналог new(std::nothrow). Типа попробовали выделить память, если не получилось, то у нас на руках нулевой указатель и мы можем попробовать обработать эту ситуацию без try..catch блока (ведь try..catch -- это дорого).&lt;/p&gt;

&lt;p&gt;Мне кажется, что в memory_resource напрашивается метод allocate формата:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;void *
allocate(std::nothrow_t,
  std::size_t bytes,
  std::size_t alignment = alignof(std::max_align_t));
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;и соответствующий ему метод do_allocate.&lt;/p&gt;

&lt;p&gt;Но почему-то этого нет 🙁&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;У аллокатора есть свойство, которые выражаются вложенным типом propagate_on_container_copy_assignment. Если оно эквивалентно std::true_type, то аллокатор должен копироваться при копировании содержимого контейнера в операторе копирования.&lt;/p&gt;

&lt;p&gt;При этом у аллокатора есть метод select_on_container_copy_construction, который должен вызываться у аллокатора в конструкторе копирования контейнера. Т.е. вот в этом случае:&lt;/p&gt;

&lt;code&gt;&lt;pre&gt;some_container original{ ... };
...
some_container copy{ original }; // (1)
&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;В точке (1) должен быть вызов original.get_allocator().select_on_container_copy_construction().&lt;/p&gt;

&lt;p&gt;Что мне кажется странным и несколько недодуманным, так это то, что потенциально propagate_on_container_copy_assignment и select_on_container_copy_construction могут быть не согласованы.&lt;/p&gt;

&lt;p&gt;Т.е. свойство propagate_on_container_copy_assignment может быть std::false_type (а по умолчанию это так и есть), при этом select_on_container_copy_construction может возвращать тот же самый аллокатор. Что приведет к тому, что в конструкторе копирования у нас будет копироваться аллокатор из контейнера-источника. А вот в операторе копирования мы аллокатор из источника копировать уже не будем.&lt;/p&gt;

&lt;p&gt;А может быть и другой вариант: propagate_on_container_copy_assignment -- это std::true_type, тогда как select_on_container_copy_construction будет возвращать новый экземпляр аллокатора (не равный исходному). Тогда в конструкторе копирования мы будем получать новый экземпляр аллокатора, а в операторе копирования -- будем получать копию аллокатора из контейнера-источника.&lt;/p&gt;

&lt;p&gt;И за отсутствием таких рассогласований должен следить сам программист. Не то, чтобы это было сложно, но там где есть вероятность что-то забыть, рано или поздно вероятность воплотится в действительность.&lt;/p&gt;

&lt;p&gt;Конкретно эту штуку, наверное, нельзя назвать недоделкой. Но не покидает впечатление, что есть во всей этой кухне некоторая недосказанность, разбираться которой приходится каждому, кто погружается в тему аллокаторов. Не менее вероятно, что я просто не понимаю всей глубины замыслов авторов этой части стандартной библиотеки.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/3666370001388055947/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/3666370001388055947' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/3666370001388055947'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/3666370001388055947'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/03/progc-c.html' title='[prog.c++] Как будто бы недоделки в системе C++ных аллокаторов'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-8804616857673741350</id><published>2026-03-02T10:02:00.002+03:00</published><updated>2026-03-02T11:27:37.554+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Из непонятого"/><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Применимость идиом copy-then-swap и move-then-swap при наличии кастомных аллокаторов</title><content type='html'>&lt;p&gt;В продолжение недавно начатой &lt;a href=&quot;https://eao197.blogspot.com/2026/02/progc-vectoroperatorconst-vector.html&quot;&gt;темы&lt;/a&gt;. Есть очень удобная идиома copy-then-swap, которая позволяет легко и просто написать для своего типа оператор копирования, обеспечивающий строгую гарантию безопасности исключений.&lt;/p&gt;

&lt;p&gt;Для примера рассмотрим некий вымышленный тип, который содержит внутри пару векторов:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;class&lt;/font&gt;&amp;nbsp;special_container {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;description { ... };&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;payload { ... };&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;std::vector&amp;lt;description&amp;gt; m_descriptions;&lt;br&gt;
&amp;nbsp;&amp;nbsp;std::vector&amp;lt;payload&amp;gt; m_payloads;&lt;br&gt;
...&lt;br&gt;
};&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;И мы хотим, чтобы у special_container был оператор копирования со строгой гарантией безопасности исключений. Для этого нам потребуются:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;обычный конструктор копирования;&lt;/li&gt;
  &lt;li&gt;не бросающий исключений swap.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;что достигается весьма просто:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;class&lt;/font&gt;&amp;nbsp;special_container {&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Swap сделаем через свободную функцию.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;friend&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;void&lt;/font&gt;&amp;nbsp;swap(special_container &amp;amp; a, special_container &amp;amp; b)&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;noexcept&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;std::swap;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;swap(a.m_descriptions, b.m_descriptions);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;swap(a.m_payloads, b.m_payloads);&lt;br&gt;
&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Конструктор копирования.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container(&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;special_container &amp;amp; other)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: m_descriptions{ other.m_descriptions }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, m_payloads{ other.m_payloads }&lt;br&gt;
&amp;nbsp;&amp;nbsp;{}&lt;br&gt;
...&lt;br&gt;
};&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Имея в своем распоряжении эти базовые инструменты можно сделать и оператор копирования:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
special_container &amp;amp;&lt;br&gt;
special_container::&lt;font color=&quot;#ffff60&quot;&gt;operator&lt;/font&gt;=(&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;special_container &amp;amp; other)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container tmp{ other };&lt;br&gt;
&amp;nbsp;&amp;nbsp;swap(*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;, tmp);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;return&lt;/font&gt;&amp;nbsp;*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;;&lt;br&gt;
}&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Фокус здесь в том, что возможные исключения вылетят при формировании объекта tmp. Но при этом ничего не меняется в this. А если при конструировании tmp исключений не случилось, то мы заменяем содержимое this содержимым tmp.&lt;/p&gt;

&lt;p&gt;Еще один приятный фокус в том, что такая примитивная реализация прекрасно защищает и от присваивания самому себе. Впрочем, если экземпляры special_container &quot;тяжелые&quot;, а вероятности самоприсваивания не нулевая, то можно и по старинке:
&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
special_container &amp;amp;&lt;br&gt;
special_container::&lt;font color=&quot;#ffff60&quot;&gt;operator&lt;/font&gt;=(&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;special_container &amp;amp; other)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;if&lt;/font&gt;(&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;&amp;nbsp;!= std::addressof(other))&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;special_container tmp{ other };&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;swap(*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;, tmp);&lt;br&gt;
&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;return&lt;/font&gt;&amp;nbsp;*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;;&lt;br&gt;
}&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Пока что все идет замечательно.&lt;/p&gt;

&lt;p&gt;Но давайте представим себе, что нам потребовалось научить special_container работать с разными аллокаторами. Т.е. тип special_container превращается во что-то вроде:&lt;/p&gt;


&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;Alloc&amp;gt;&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;class&lt;/font&gt;&amp;nbsp;special_container&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;description {};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;payload {};&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;alloc_traits = std::allocator_traits&amp;lt;Alloc&amp;gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;description_allocator = alloc_traits::&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;nbsp;rebind_alloc&amp;lt;description&amp;gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;payload_allocator = alloc_traits::&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;nbsp;rebind_alloc&amp;lt;payload&amp;gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;std::vector&amp;lt;description, description_allocator&amp;gt; m_descriptions;&lt;br&gt;
&amp;nbsp;&amp;nbsp;std::vector&amp;lt;payload, payload_allocator&amp;gt; m_payloads;&lt;br&gt;
...&lt;br&gt;
};&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Сможем ли мы и дальше пользоваться идиомой copy-then-swap?&lt;/p&gt;

&lt;p&gt;И вот тут у меня есть сомнения. А в попытках разобраться как раз и получился этот пост.&lt;/p&gt;

&lt;p&gt;У аллокатора может быть такое свойство как propagate_on_container_swap. Если это свойство выставлено в std::true_type, то при выполнении swap мы можем обменять аллокаторы для контейнеров.&lt;/p&gt;

&lt;p&gt;Грубо говоря, допустим, что у нас есть собственный тип аллокатора:&lt;/p&gt;

&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;class&lt;/font&gt;&amp;nbsp;special_allocator {&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Указываем, что обмен аллокаторами поддерживается.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;propagate_on_container_swap :&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;&amp;nbsp;std::true_type {};&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Явно говорим, что экземпляры аллокаторов отличаются.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;is_always_equal :&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;&amp;nbsp;std::false_type {};&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
};&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;В этом случае мы можем сделать вот так:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
special_allocator first_allocator{...};&lt;br&gt;
special_allocator second_allocator{...};&lt;br&gt;
assert(first_allocator != second_allocator);&lt;br&gt;
&lt;br&gt;
std::vector&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;int&lt;/font&gt;, special_allocator&amp;gt; first{ first_allocator };&lt;br&gt;
std::vector&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;int&lt;/font&gt;, special_allocator&amp;gt; second{ second_allocator };&lt;br&gt;
...&lt;br&gt;
swap(first, second);&lt;br&gt;

      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Т.е. пока что все вроде бы понятно и логично.&lt;/p&gt;

&lt;p&gt;Но что, если propagate_on_container_swap определен как std::false_type (или не определен, что приравнивается к std::false_type)?&lt;/p&gt;

&lt;p&gt;В этом случае обмен аллокаторами при выполнении swap невозможен.&lt;/p&gt;

&lt;p&gt;Более того, если у контейнеров аллокаторы не равны, то выполнение swap уже является undefined behaviour. Т.е. вот в этом случае:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;class&lt;/font&gt;&amp;nbsp;special_allocator {&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Указываем, что обмен аллокаторами НЕ поддерживается.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;propagate_on_container_swap :&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;&amp;nbsp;std::false_type {};&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Явно говорим, что экземпляры аллокаторов отличаются.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;is_always_equal :&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;&amp;nbsp;std::false_type {};&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
};&lt;br&gt;
std::vector&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;int&lt;/font&gt;, special_allocator&amp;gt; first{ first_allocator };&lt;br&gt;
std::vector&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;int&lt;/font&gt;, special_allocator&amp;gt; second{ second_allocator };&lt;br&gt;
assert(first_allocator != second_allocator);&lt;br&gt;
...&lt;br&gt;
swap(first, second);&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Мы получаем UB.&lt;/p&gt;

&lt;p&gt;И знаете, что интересно?&lt;/p&gt;

&lt;p&gt;Что у штатных аллокаторов в стандартной библиотеке С++, например, у std::allocator и std::pmr::polymorphic_allocator свойство propagate_on_container_swap выставлено в std::false_type.&lt;/p&gt;

&lt;p&gt;И если для std::allocator это компенсируется значением is_always_equal, то вот для std::pmr::polymorphic_allocator еще и is_always_equal является std::false_type.&lt;/p&gt;

&lt;p&gt;Получается, что как только я делаю special_container шаблоном, параметризуемым типом аллокатора, то реализация оператора копирования через идиому copy-then-swap становится некорректной.&lt;/p&gt;

&lt;p&gt;Давайте взглянем на нее еще раз:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;Alloc&amp;gt;&lt;br&gt;
special_container&amp;lt;Alloc&amp;gt; &amp;amp;&lt;br&gt;
special_container&amp;lt;Alloc&amp;gt;::&lt;font color=&quot;#ffff60&quot;&gt;operator&lt;/font&gt;=(&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;special_container&amp;lt;Alloc&amp;gt; &amp;amp; other)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container tmp{ other };&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// (1)&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;swap(*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;, tmp);&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// (2)&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;return&lt;/font&gt;&amp;nbsp;*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;;&lt;br&gt;
}&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Здесь в точке (1) мы получаем новый контейнер, у которого будет собственный аллокатор. И этот аллокатор может отличаться от аллокатора, который есть у this.&lt;/p&gt;

&lt;p&gt;Соответственно, операция swap может вести к UB если:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;у аллокатора свойство propagate_on_container_swap -- это std::false_type;&lt;/li&gt;
  &lt;li&gt;у аллокатора свойство is_aways_equal -- это std::false_type;&lt;/li&gt;
  &lt;li&gt;у tmp и this не равные друг другу экземпляры аллокаторов.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Т.е. вот в этом случае:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;class&lt;/font&gt;&amp;nbsp;special_allocator {&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Указываем, что обмен аллокаторами НЕ поддерживается.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;propagate_on_container_swap :&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;&amp;nbsp;std::false_type {};&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Явно говорим, что экземпляры аллокаторов отличаются.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;is_always_equal :&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;&amp;nbsp;std::false_type {};&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
};&lt;br&gt;
&lt;br&gt;
special_allocator first_allocator{...};&lt;br&gt;
special_allocator second_allocator{...};&lt;br&gt;
assert(first_allocator != second_allocator);&lt;br&gt;
&lt;br&gt;
special_container&amp;lt;special_allocator&amp;gt; first{ first_allocator };&lt;br&gt;
special_container&amp;lt;special_allocator&amp;gt; second{ second_allocator };&lt;br&gt;
...&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Наполнение контейнеров.&lt;/font&gt;&lt;br&gt;
first = second;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// (3)&lt;/font&gt;&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;в точке (3) у нас будет UB из-за использования swap-а в реализации operator= для special_container.&lt;/p&gt;

&lt;p&gt;Как я смог понять, выход в том, чтобы при создании tmp внутри operator= явным образом задать для tmp нужный allocator. Что-то вроде:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;Alloc&amp;gt;&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;class&lt;/font&gt;&amp;nbsp;special_container&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;description {};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;payload {};&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;alloc_traits = std::allocator_traits&amp;lt;Alloc&amp;gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;description_allocator = alloc_traits::&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;nbsp;rebind_alloc&amp;lt;description&amp;gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;payload_allocator = alloc_traits::&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;nbsp;rebind_alloc&amp;lt;payload&amp;gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Аллокатор, который мы будем использовать.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;Alloc m_allocator;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;std::vector&amp;lt;description, description_allocator&amp;gt; m_descriptions;&lt;br&gt;
&amp;nbsp;&amp;nbsp;std::vector&amp;lt;payload, payload_allocator&amp;gt; m_payloads;&lt;br&gt;
...&lt;br&gt;
&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Специальный вариант конструктора копирования, который получает&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// экземпляр аллокатора.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Откуда берем содержимое.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;special_container &amp;amp; other,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Аллокатор, который должны использовать.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;Alloc &amp;amp; allocator)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: m_allocator{ allocator }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, m_descriptions{ other.m_descriptions, m_allocator }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, m_payloads{ other.m_payloads, m_allocator }&lt;br&gt;
&amp;nbsp;&amp;nbsp;{}&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Оператор копирования.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container &amp;amp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;operator&lt;/font&gt;=(&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;special_container &amp;amp; other)&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Делаем копию other, но с использованием нашего аллокатора.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;special_container tmp{ other, m_allocator };&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Теперь безопасно делаем swap, т.к. даже если у аллокатора&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// propagate_on_container_swap -- это std::false_type, то все&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// равно аллокатор в tmp и в this один и тот же.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;swap(*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;, tmp);&lt;br&gt;
&amp;nbsp;&amp;nbsp;}&lt;br&gt;
};&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;И тут, казалось бы, можно было бы поставить точку и выдохнуть. Если бы не одно &quot;но&quot;: у аллокатора есть свойство propagate_on_container_copy_assignment. Если оно соответствует std::true_type, то при копировании контейнеров должно происходить копирование аллокатора. Т.е. в этом случае мы не можем создать tmp с использованием старого аллокатора.&lt;/p&gt;

&lt;p&gt;И тут начинает казаться, что с учетом свойства propagate_on_container_copy_assignment проще делать оператор копирования без идиомы copy-then-swap:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;Alloc&amp;gt;&lt;br&gt;
special_container&amp;lt;Alloc&amp;gt; &amp;amp;&lt;br&gt;
special_container&amp;lt;Alloc&amp;gt;::&lt;font color=&quot;#ffff60&quot;&gt;operator&lt;/font&gt;=(&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;special_container&amp;lt;Alloc&amp;gt; &amp;amp; other)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;if&lt;/font&gt;(&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;&amp;nbsp;!= std::addressof(other))&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_descriptions = other.m_descriptions;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// (4)&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_payloads = other.m_payloads;&lt;br&gt;
&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;return&lt;/font&gt;&amp;nbsp;*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;;&lt;br&gt;
}&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Ведь в этой тривиальной реализации все должно бы произойти автоматически: если propagate_on_container_copy_assignment предписывает копировать аллокатор, то это произойдет автоматически при копировании m_descriptions и m_payloads. А если копировать аллокаторы не нужно, то это также автоматически будет учтено в тех же самых копированиях.&lt;/p&gt;

&lt;p&gt;Однако, при этом мы имеем только базовую гарантию безопасности исключений. И достаточно специфическую. Давайте представим себе, что аллокатор требует своего копирования (т.е. propagate_on_container_copy_assignment -- это std::true_type). И исключение у нас происходит в точке (4).&lt;/p&gt;

&lt;p&gt;В этом случае в m_descriptions, скорее всего, уже будет аллокатор из other. Но в каком состоянии содержимое m_descriptions -- мы толком не знаем. Старого содержимого там, наверняка, уже нет. А вот что там из нового -- непонятно.&lt;/p&gt;

&lt;p&gt;Тогда как m_payloads мы тронуть еще не успели и он остался в своем исходном виде. Со своим первоначальным аллокатором.&lt;/p&gt;

&lt;p&gt;Как по мне, так получить экземпляр special_container в таком неопределенном состоянии -- это то еще удовольствие. Поэтому есть ощущение, что можно было бы сделать так:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;Alloc&amp;gt;&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;class&lt;/font&gt;&amp;nbsp;special_container&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;description {};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;payload {};&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;alloc_traits = std::allocator_traits&amp;lt;Alloc&amp;gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;description_allocator = alloc_traits::&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;nbsp;rebind_alloc&amp;lt;description&amp;gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;payload_allocator = alloc_traits::&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;nbsp;rebind_alloc&amp;lt;payload&amp;gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Содержимое контейнера. Собрано в одном месте дабы проще&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// было его полностью заменять.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;content&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Аллокатор, который мы будем использовать.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Alloc m_allocator;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::vector&amp;lt;description, description_allocator&amp;gt; m_descriptions;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::vector&amp;lt;payload, payload_allocator&amp;gt; m_payloads;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content(&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;Alloc &amp;amp; alloc)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: m_allocator{ alloc }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, m_descriptions{ alloc }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, m_payloads{ alloc }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content(&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;Alloc &amp;amp; alloc,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;std::vector&amp;lt;description, description_allocator&amp;gt; &amp;amp; descriptions,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;std::vector&amp;lt;payload, payload_allocator&amp;gt; &amp;amp; payloads)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: m_allocator{ alloc }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, m_descriptions{ descriptions, alloc }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;, m_payloads{ payloads, alloc }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Для перемещения нам достаточно того, что сгенерирует компилятор.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content(content &amp;amp;&amp;amp; other)&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;noexcept&lt;/font&gt;&amp;nbsp;=&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;default&lt;/font&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;};&lt;br&gt;
&amp;nbsp;&amp;nbsp;content m_content;&lt;br&gt;
...&lt;br&gt;
&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Выполнение требований к allocator aware container.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;allocator_type = Alloc;&lt;br&gt;
&amp;nbsp;&amp;nbsp;[[nodiscard]] allocator_type&lt;br&gt;
&amp;nbsp;&amp;nbsp;get_allocator()&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;{&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;return&lt;/font&gt;&amp;nbsp;m_content.m_allocator; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Специальный вариант конструктора копирования, который получает&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// экземпляр аллокатора.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Откуда берем содержимое.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;special_container &amp;amp; other,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Аллокатор, который должны использовать.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;Alloc &amp;amp; allocator)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: m_content{ allocator, other.m_descriptions, other.m_payloads }&lt;br&gt;
&amp;nbsp;&amp;nbsp;{}&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Оператор копирования.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container &amp;amp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;operator&lt;/font&gt;=(&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;special_container &amp;amp; other)&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;if&lt;/font&gt;(&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;&amp;nbsp;!= std::addressof(other))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Определяем какой именно аллокатор должен использоваться в копии.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;auto&lt;/font&gt;&amp;nbsp;&amp;amp; new_copy_alloc =&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alloc_traits::propagate_on_container_copy_assignment::value&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;? other.get_allocator()&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Нужно забирать из other.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;:&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;-&amp;gt;get_allocator()&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Нужно оставлять свой.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Первая часть copy-then-swap.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;content new_content{ new_copy_alloc, other.m_descriptions, other.m_payloads };&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;//&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;//&amp;nbsp;&amp;nbsp;ВАЖНО: ниже по коду исключений уже не ждем.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;//&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Вторая часть copy-then-swap состоит из уничтожения текущего content...&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_content.~content();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// ...и его пересоздания по месту.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;new&lt;/font&gt;(m_content) content{ std::move(new_content) };&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;return&lt;/font&gt;&amp;nbsp;*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;}&lt;br&gt;
};&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Понятное дело, что в таком случае придется всю работу с m_content в special_container делать через std::launder. Но это уже дело техники.&lt;/p&gt;

&lt;p&gt;При таком подходе, как мне думается, как раз получается обеспечить строгую гарантию безопасности исключений для операции присваивания даже при необходимости замены аллокатора. При этом мы также достигаем и выполнения требования стандарта (т.е. свойство propagate_on_container_copy_assignment корректно обрабатывается).&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Отдельным моментом стоит использование идиомы move-then-swap в реализации оператора перемещения.&lt;/p&gt;

&lt;p&gt;Пока мы не связываемся с аллокаторами, у нас нет проблем с оператором перемещения, который красиво и просто делается через move-then-swap:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
special_container::special_container(special_container &amp;amp;&amp;amp; other)&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;noexcept&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;: m_descriptions{ std::exchange(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;other.m_descriptions, std::vector&amp;lt;description&amp;gt;{}) }&lt;br&gt;
&amp;nbsp;&amp;nbsp;, m_payloads{ std::exchange(&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;other.m_payloads, std::vector&amp;lt;payload&amp;gt;{}) }&lt;br&gt;
{}&lt;br&gt;
&lt;br&gt;
special_container &amp;amp;&lt;br&gt;
special_container::&lt;font color=&quot;#ffff60&quot;&gt;operator&lt;/font&gt;=(special_container &amp;amp;&amp;amp; other)&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;noexcept&lt;/font&gt;&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container tmp{ std::move(other) };&lt;br&gt;
&amp;nbsp;&amp;nbsp;swap(*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;, tmp);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;return&lt;/font&gt;&amp;nbsp;*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;;&lt;br&gt;
}&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Но вот как только в дело вступают аллокаторы, так все становится гораздо интереснее.&lt;/p&gt;

&lt;p&gt;Есть ощущение, что в таком случае будет что-то вроде:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;Alloc&amp;gt;&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;class&lt;/font&gt;&amp;nbsp;special_container&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;description {};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;struct&lt;/font&gt;&amp;nbsp;payload {};&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;alloc_traits = std::allocator_traits&amp;lt;Alloc&amp;gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;description_allocator = alloc_traits::&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;nbsp;rebind_alloc&amp;lt;description&amp;gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;payload_allocator = alloc_traits::&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;nbsp;rebind_alloc&amp;lt;payload&amp;gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Можно ли делать нормальный не бросающий move.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;using&lt;/font&gt;&amp;nbsp;is_nonthrowing_move_possible = std::conditional_t&amp;lt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alloc_traits::propagate_on_container_move_assignment::value ||&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alloc_traits::is_always_equal::value,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::true_type,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::false_type&amp;gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Аллокатор, который мы будем использовать.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;Alloc m_allocator;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Содержимое контейнера.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;std::vector&amp;lt;description, description_allocator&amp;gt; m_descriptions;&lt;br&gt;
&amp;nbsp;&amp;nbsp;std::vector&amp;lt;payload, payload_allocator&amp;gt; m_payloads;&lt;br&gt;
...&lt;br&gt;
&lt;font color=&quot;#ffff60&quot;&gt;public&lt;/font&gt;:&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Конструктор перемещения.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Вполне достаточно того, что генерирует компилятор.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container(special_container &amp;amp; other)&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;noexcept&lt;/font&gt;&amp;nbsp;=&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;default&lt;/font&gt;;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Оператор перемещения.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;special_container &amp;amp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;operator&lt;/font&gt;=(special_container &amp;amp;&amp;amp; other)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;noexcept&lt;/font&gt;( is_nonthrowing_move_possible::value )&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Вот здесь нам обязательно нужна защита от самоприсваивания.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;if&lt;/font&gt;(&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;&amp;nbsp;!= std::addressof(other))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Замена аллокатора только если это разрешается самим аллокатором.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;if&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;constexpr&lt;/font&gt;(alloc_traits::propagate_on_container_move_assignment::value)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Эта штука, по идее, бросать исключения не должна.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_allocator = std::move(other.m_allocator);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// А вот здесь у нас либо исключений не будет, либо они возможны,&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// но все это обрабатывается внутри std::vector::operator=.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_descriptions = std::move(other.m_descriptions);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_payloads = std::move(other.m_payloads);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;return&lt;/font&gt;&amp;nbsp;*&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;}&lt;br&gt;
};&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;hr/&gt;

&lt;p&gt;Спасибо всем, кто дочитал до финала. Приношу свои извинения за такой объем сумбурного текста без четко оформленных выводов. В этом посте я пытался зафиксировать свои мысли по ходу изучения вопроса реализации собственного &lt;a href=&quot;https://en.cppreference.com/w/cpp/named_req/AllocatorAwareContainer.html&quot;&gt;AllocatorAwareContainer-а&lt;/a&gt;. И несмотря на все написанное выше у меня пока что нет ощущения, что удалось это сделать.&lt;/p&gt;

&lt;p&gt;Буду признателен, если в моих рассуждениях обнаружатся ошибки или недоработки, на которые мне любезно укажут.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/8804616857673741350/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/8804616857673741350' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/8804616857673741350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/8804616857673741350'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/03/progc-copy-then-swap-move-then-swap.html' title='[prog.c++] Применимость идиом copy-then-swap и move-then-swap при наличии кастомных аллокаторов'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-7491421973122814292</id><published>2026-03-01T08:48:00.000+03:00</published><updated>2026-03-01T08:48:07.779+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Кино"/><category scheme="http://www.blogger.com/atom/ns#" term="О жизни"/><category scheme="http://www.blogger.com/atom/ns#" term="Ссылки"/><title type='text'>[life.cimena] Очередной кинообзор (2026/02)</title><content type='html'>&lt;p&gt;Традиционный отчет о просмотренных за минувший месяц фильмах. Как обычно, в начале каждого из списков идет то, что понравилось больше, а в конце то, на что время можно и не тратить.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Фильмы&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/252900/&quot;&gt;Человек с Земли (The Man from Earth, 2007)&lt;/a&gt;. Фильм очень не новый, но посмотрел его только сейчас. Как по мне, так отличное кино, базирующееся на хорошем сюжете и тщательно выстроенных диалогах.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/hollywood/204820/annot/&quot;&gt;Убежище (Shelter, 2025)&lt;/a&gt;. Обычный боевик со Стетхемом в главной роли, где круче него только горы и яйца. Но, в отличии от совсем уж сказочных &quot;Пчеловода&quot; и &quot;Мастера&quot;, этот смотрится вполне нормально.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/8803672/&quot;&gt;Убийца в петле времени (Kill Me Again, 2023)&lt;/a&gt;. На удивление хорошо. Тот редкий случай, когда не ждешь вообще ничего хорошего, а получаешь нормально сделанное кино с вменяемой развязкой. Ну и, прямо скажем, неожиданная вариация на тему &quot;дня сурка&quot;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/7297462/&quot;&gt;Бастион 36 (Bastion 36, 2025)&lt;/a&gt;. Неплохая криминальная драма. Но мне не хватало динамики, какие-то эпизоды просто проматывал, т.к. ну очень уж скучно было.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/5453060/&quot;&gt;Казнить нельзя помиловать (Mercy, 2026)&lt;/a&gt;. Первые 2/3 было прям хорошо. Затем началось что-то невнятное в виде погони и вокруг нее, что очень сильно испортило впечатление. В конце есть хороший твист, который, к сожалению, испорченное впечатление исправить уже не смог.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Сериалы&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/5378574/&quot;&gt;Мошенники (второй сезон, 2026)&lt;/a&gt;. Отличное продолжение отличного сериала.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/462649/&quot;&gt;Ночной администратор (The Night Manager, второй сезон, 2025)&lt;/a&gt;. Если понравился первый сезон, то можно посмотреть и второй. Местами второй похуже (мне выбор некоторых актеров показался странным), местами получше. Буду ждать продолжения.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/5267249/&quot;&gt;Золотое дно (второй сезон, 2025)&lt;/a&gt;. Похуже первого сезона. Но тут явно просто промежуточный этап, который даже не стали доводить до логического завершения, а просто резко оборвали на половине. Мол ждите третьего сезона. Ну подождем. Хотя вряд ли там будет что-то хорошее.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/5364758/&quot;&gt;Вторая семья (первый сезон, 2023)&lt;/a&gt;. Купился на очень высокий рейтинг на Кинопоиске. Как по мне, средней паршивости. Основной сюжет вроде норм, но некоторые детали оставляют вопросы &quot;ну как так-то?&quot;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/9416511/&quot;&gt;Его и её (His &amp;amp; Hers, первый сезон 2026)&lt;/a&gt;. Смотрибельно, хотя идиотизм некоторых персонажей меня откровенно раздражал. Финал неожиданный, но, как по мне, выглядит несколько чужеродно и притянуто за уши.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kino-teatr.ru/kino/movie/ros/194636/annot/&quot;&gt;Художник (второй сезон, 2025)&lt;/a&gt;. Начало еще более-менее смотрибельно, но вот завершение -- это просто какой-то позор.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/7491421973122814292/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/7491421973122814292' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/7491421973122814292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/7491421973122814292'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/03/lifecimena-202602.html' title='[life.cimena] Очередной кинообзор (2026/02)'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-6365916246392153550</id><published>2026-02-27T19:10:00.000+03:00</published><updated>2026-02-27T19:10:23.617+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Обеспечивает ли vector::operator=(const vector &amp;) строгую гарантию безопасности исключений?</title><content type='html'>&lt;p&gt;Если задать какому-нибудь ИИ простой вопрос о гарантиях безопасности исключений оператора присваивания для std::vector, то можно получить однозначный ответ: мол, обеспечивается строгая гарантия. Т.е. если в процессе работы оператора копирования возникнет исключение, то целевой вектор останется в своем исходном виде.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg26V7cIH3DN76_rRNzCIQWtfnNcsOjgRxDzRPdakIS1UiNqzhWXO79q43E5V193rMw33nq5ADESjbHuaUbqaq1ZRdvsdLlZSDeFCGUWxzLof5bluTLr3CsOhnWxhFi75D971XAFpJ-oTxTqytenimhi6QbFcDTAVTo7fgJ15wmPurB576TEwOOK50eI7A/s1534/Screenshot_20260227_163735.png&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;600&quot; data-original-height=&quot;1494&quot; data-original-width=&quot;1534&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg26V7cIH3DN76_rRNzCIQWtfnNcsOjgRxDzRPdakIS1UiNqzhWXO79q43E5V193rMw33nq5ADESjbHuaUbqaq1ZRdvsdLlZSDeFCGUWxzLof5bluTLr3CsOhnWxhFi75D971XAFpJ-oTxTqytenimhi6QbFcDTAVTo7fgJ15wmPurB576TEwOOK50eI7A/s600/Screenshot_20260227_163735.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOJ0kohSWDRQYCb34-kda8MXsIjzeG0uJ3izP7gzSSaJCzoZKqR5Ix2CbnmIv3dDNJRqDE25z6f30croamuebtccf_14tBNKPHOyh-giiGSH7wC9jgewLpK9aP2f2Y2Y4BL-LeouF-w2bwUhpPPXr-R3pog-6VrjnRnxkbGoa-OdYYxuk_Hlt-6wn-h_I/s1743/Screenshot_20260227_163656.png&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;600&quot; data-original-height=&quot;971&quot; data-original-width=&quot;1743&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOJ0kohSWDRQYCb34-kda8MXsIjzeG0uJ3izP7gzSSaJCzoZKqR5Ix2CbnmIv3dDNJRqDE25z6f30croamuebtccf_14tBNKPHOyh-giiGSH7wC9jgewLpK9aP2f2Y2Y4BL-LeouF-w2bwUhpPPXr-R3pog-6VrjnRnxkbGoa-OdYYxuk_Hlt-6wn-h_I/s600/Screenshot_20260227_163656.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Однако, не все так однозначно™&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Пункт первый, далеко не очевидный&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;std::vector зависит от аллокатора. Хотя, наверное, мало кому доводилось использовать std::vector с аллокатором, отличным от std::allocator. Тем не менее, у вектора есть аллокатор. А у аллокатора есть такое свойство как propagate_on_container_copy_assignment (см., например, &lt;a href=&quot;https://en.cppreference.com/w/cpp/named_req/Allocator.html&quot;&gt;здесь&lt;/a&gt;). И если это свойство предписывает скопировать в вектор-приемник аллокатор из вектора-источника, то тут возникает тонкий момент: старое содержимое вектора-источника должно быть удалено посредством старого аллокатора.&lt;/p&gt;

&lt;p&gt;Если глянуть как этот момент учитывается в реализациях стандартной библиотеки (&lt;a href=&quot;https://github.com/gcc-mirror/gcc/blob/654026083af3fed619ad23445ba7513d4d4b6a66/libstdc%2B%2B-v3/include/bits/vector.tcc#L221&quot;&gt;libstdc++ от GCC&lt;/a&gt; или &lt;a href=&quot;https://github.com/llvm/llvm-project/blob/fc69531254ca9e81fd4371c68e7fd74fe4b9527a/libcxx/include/__vector/vector.h#L1022&quot;&gt;libcxx от LLVM&lt;/a&gt;), то можно увидеть, что сперва уничтожается старое содержимое вектора, и лишь затем делается попытка копирования содержимого вектора источника.&lt;/p&gt;

&lt;p&gt;Особенно хорошо это видно на примере libstdc++v3:&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPO-0JhyhdCIx3qAveL8JhaEI8EynqxCraIO0pErcAazNJsInLqxemY8KtzbUspboDiNzhIVTAwt73cbjGZDvz-O7TOWBrGnqKG3G07dsY3Y_wcs3WCyCcDYK7GtP7Vt2V9tPcJ9yUJpGg-bPh5uVQRKcRYzwh6mX4GAbgFgf3d6QYwF8k00EPJaUFrAw/s1773/Screenshot_20260227_164720.png&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;600&quot; data-original-height=&quot;1773&quot; data-original-width=&quot;1409&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPO-0JhyhdCIx3qAveL8JhaEI8EynqxCraIO0pErcAazNJsInLqxemY8KtzbUspboDiNzhIVTAwt73cbjGZDvz-O7TOWBrGnqKG3G07dsY3Y_wcs3WCyCcDYK7GtP7Vt2V9tPcJ9yUJpGg-bPh5uVQRKcRYzwh6mX4GAbgFgf3d6QYwF8k00EPJaUFrAw/s600/Screenshot_20260227_164720.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Вначале удаляется старое содержимое вектора-приемника, а затем (когда вектор-приемник стал пустым) выделяется новый блок памяти куда копируется содержимое вектора-источника.&lt;/p&gt;

&lt;p&gt;Получается, что если при аллокации нового блока у нас возникнет исключение, что вектор-приемник окажется пустым. А это всего лишь базовая гарантия безопасности исключений, а не строгая.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Пункт второй, более очевидный&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Многое зависит еще и от того, какие гарантии безопасности исключений дает сам тип T, который хранится в vector-е. Если посмотреть на одну из ветвей работы оператора присваивания в libstdc++v3, то можно увидеть, что новое содержимое записывается поверх старого:&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiX2d3_IllNIWqK2pHqGVvxJwe781OQd8gt2WyNnIHtfB3MPegGPLqEb3khGg2s8I0a9XTQYq1cLfbgI14MzisljUkSfrTqQhrVcnmjB4eODArTuIOVomXdmPmKAbhoJ7QjCzOg4ecQ54eOY_sqLjU6VqrEk-6yXiuBuKAdJSGXB7gNoCUPUH7ushce_U/s1345/Screenshot_20260227_181059.png&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;600&quot; data-original-height=&quot;888&quot; data-original-width=&quot;1345&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiX2d3_IllNIWqK2pHqGVvxJwe781OQd8gt2WyNnIHtfB3MPegGPLqEb3khGg2s8I0a9XTQYq1cLfbgI14MzisljUkSfrTqQhrVcnmjB4eODArTuIOVomXdmPmKAbhoJ7QjCzOg4ecQ54eOY_sqLjU6VqrEk-6yXiuBuKAdJSGXB7gNoCUPUH7ushce_U/s600/Screenshot_20260227_181059.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;А раз так, то мы сильно зависим от того, бросают ли исключения операторы копирования у T. Если бросают, то может случиться следующее:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;первые N элементов из вектора-источника будут скопированы;&lt;/li&gt;
&lt;li&gt;на (N+1) элементе возникнет исключение, операция копирования будет прервана.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Получится, что первые N элементов у вектора-приемника получат новые значения, а оставшиеся -- сохранят старые. При это непонятно что будет с (N+1): если у T::operator= строгая гарантия безопасности исключений, то сохранится старое. А вот если нет... Тогда этот элемент окажется в непонятном состоянии.&lt;/p&gt;

&lt;p&gt;В сухом же остатке имеем то, что если в операторе копирования для вектора возникнет исключение в T::operator=, то вектор может изменить свое состояние (часть будет иметь новое значение, часть старое). А это никакая не строгая гарантия безопасности.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;В общем, как мне думается, если мы хотим гарантировать себе откат вектора-приемника к исходному виду при присваивании, то следует делать что-то вроде:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;T,&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;Alloc&amp;gt;&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;void&lt;/font&gt;&amp;nbsp;strong_guarantee_copy(vector&amp;lt;T, Alloc&amp;gt; &amp;amp; dest,&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;vector&amp;lt;T, Alloc&amp;gt; &amp;amp; src)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;vector&amp;lt;T, Alloc&amp;gt; fresh_copy{ src, dest.get_allocator() };&lt;br&gt;
&amp;nbsp;&amp;nbsp;swap(dest, fresh_copy);&lt;br&gt;
}&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;В этом случае мы сперва получаем копию. Или исключение, если копия не создается по каким-либо причинам. А уже потом перемещаем это новое значение в dest.&lt;/p&gt;

&lt;p&gt;Хотя, в случае с кастомными аллокаторами может быть не так радостно. Но об этом я бы хотел поговорить в другой раз.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/6365916246392153550/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/6365916246392153550' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/6365916246392153550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/6365916246392153550'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/02/progc-vectoroperatorconst-vector.html' title='[prog.c++] Обеспечивает ли vector::operator=(const vector &amp;) строгую гарантию безопасности исключений?'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg26V7cIH3DN76_rRNzCIQWtfnNcsOjgRxDzRPdakIS1UiNqzhWXO79q43E5V193rMw33nq5ADESjbHuaUbqaq1ZRdvsdLlZSDeFCGUWxzLof5bluTLr3CsOhnWxhFi75D971XAFpJ-oTxTqytenimhi6QbFcDTAVTo7fgJ15wmPurB576TEwOOK50eI7A/s72-c/Screenshot_20260227_163735.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-2305222750531681957</id><published>2026-02-20T13:16:00.000+03:00</published><updated>2026-02-20T13:16:09.577+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Дошел до чистого безумия: new(this) another_object_type</title><content type='html'>&lt;p&gt;Тяжкая судьба C++программиста довела использования в коде трюка, про который еще несколько лет назад и вовсе не знал. Речь про замену типа объекта через вызов placement new внутри метода самого заменяемого объекта.&lt;/p&gt;

&lt;p&gt;В моем случае получился код вроде вот такого:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;ValueT &amp;gt;&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;void&lt;/font&gt;&lt;br&gt;
special_map&amp;lt; ValueT &amp;gt;::fixed_capacity_node::insert_item( ValueT value )&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;auto&lt;/font&gt;&amp;nbsp;&amp;amp; self =&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;-&amp;gt;self_data();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;if&lt;/font&gt;( self.size() &amp;lt; self.capacity() )&lt;br&gt;
&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// use the existing node.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;else&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// prepare internal data for a new node type.&lt;/font&gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#80a0ff&quot;&gt;// Replace the node by an instance of the new type.&lt;/font&gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;new&lt;/font&gt;(&lt;font color=&quot;#ffff60&quot;&gt;this&lt;/font&gt;) dynamic_capacity_node{ std::move(new_node_internal_data) };&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Т.е. есть объект типа fixed_capacity_node в котором имеется контейнер для небольшого количества элементов. При вставке очередного элемента может оказаться, что этот контейнер исчерпан и нужно перейти к использованию dynamic_capacity_node вместо fixed_capacity_node. Для чего новый объект dynamic_capacity_node и создается. Но не просто так, а в той области памяти, которую только что занимал старый fixed_capacity_node объект.&lt;/p&gt;

&lt;p&gt;Еще несколько лет назад мне и в голову не приходило, что такое возможно. Однако, &lt;a href=&quot;https://eao197.blogspot.com/2022/05/progc-stdlaunder.html&quot;&gt;когда изучал тему std::launder, то наткнулся на подобный трюк&lt;/a&gt;. И вот теперь сам дошел до его применения.&lt;/p&gt;

&lt;p&gt;PS. Никому не советую повторять подобное в домашних условиях. Как говорится, все показанное было выполнено специально подготовленными профессионалами 😎 Были предприняты различные предохранительные меры дабы удостоверится, что fixed_capacty_node и dynamic_capacity_node идентичны и по размеру, и по выравниваю. И что после смены типа объекта никто не обращался к нему по старому указателю без std::launder.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/2305222750531681957/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/2305222750531681957' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2305222750531681957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2305222750531681957'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/02/progc-newthis-anotherobjecttype.html' title='[prog.c++] Дошел до чистого безумия: new(this) another_object_type'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-1937138753102908269</id><published>2026-02-09T14:22:00.000+03:00</published><updated>2026-02-09T14:22:44.929+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Business"/><category scheme="http://www.blogger.com/atom/ns#" term="Поток сознания"/><title type='text'>[business] Практические выводы из того, что успешный результат в бизнесе не гарантирован</title><content type='html'>&lt;p&gt;В догонку к &lt;a href=&quot;https://eao197.blogspot.com/2026/02/business-youtube.html&quot;&gt;предыдущему посту&lt;/a&gt;. Осталось ощущение, что сказал &quot;А&quot;, но не стал говорить &quot;Б&quot;. Посему предлагаю вернуться к теме о том, что успех в бизнесе не гарантирован и рассказать о некоторых практических выводах из этого утверждения.&lt;/p&gt;

&lt;p&gt;Не хочу войти в число тех самоуверенных бизнес-спикеров, которые категорически заявляют &quot;Делайте вот это!&quot; или &quot;Вот этого не делайте ни в коем случае!&quot; Поэтому расскажу о том, чему мне самому пришлось учиться (и я все еще в процессе). Нижеизложенное перечислено без какого-то определенного порядка и попыток приоритизации -- как вспомнилось, так и было зафиксировано.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Ожидания &quot;сейчас сделаем вот это и тогда точно взлетит&quot; не оправдываются. Поэтому было бы лучше, чтобы подобные ожидания и не возникали. Но таки возникают и ведут к сильным эмоциональным качелям: сперва ты воодушевляешься, вкладываешься, стараешься все сделать &quot;правильно&quot;, потом выкладываешь результат своего труда, ждешь реакции и... Ничего. Разочарование.&lt;/p&gt;

&lt;p&gt;Ну ничего думаешь, с первого раза не получилось. Придумываешь что-то еще, владываешься, стараешься сделать &quot;правильно&quot;, выкладываешь результат, ждешь реакции и опять ничего. Новое разочарование.&lt;/p&gt;

&lt;p&gt;И так снова и снова.&lt;/p&gt;

&lt;p&gt;Поэтому сейчас стараюсь относиться к подобным вещам с изрядной долей (возможно нездорового) пофигизма: попробуем сделать вот это и посмотрим что получится. Без каких-либо ожиданий, по сути фатализм -- если хоть как-то стрельнет, то хорошо, если не стрельнет, то и не страшно.&lt;/p&gt;

&lt;p&gt;Вот этот вот переход от &quot;и тогда точно...&quot; к &quot;посмотрим что&quot; оказался ключевым чтобы избавиться от дополнительных переживаний и нервного напряжения. Хотя бы в некоторой степени.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Когда бизнес только потребляет средства и пока еще ничего не приносит, то помогает четко обозначенный порог потерь, на которые ты готов пойти. Типа того, что определяется сумма, с которой готов расстаться. Например, вкладываю N денег в течении M месяцев. Если в итоге не выходим на окупаемость с перспективами для прибыльности, то просто закрываемся, списываем потери, осмысливаем полученные уроки и движемся дальше.&lt;/p&gt;

&lt;p&gt;Звучит просто и логично, но вот смириться с этим гораздо сложнее. Когда заданный порог приближается возникает соблазн вложить еще некоторую сумму денег. А потом еще некоторую. А потом еще. Особенно когда есть откуда эти суммы брать.&lt;/p&gt;

&lt;p&gt;Только вот, скорее всего, это всего лишь отсрочка неизбежного. И лучше таки резать сразу, не дожидаясь перитонита. Чтобы потерять только N денег, а не N умноженное на X, плюс потраченное впустую дополнительное время, которое вообще никак не вернуть.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Начинать собственный бизнес без приличной подушки безопасности так себе идея. Но идея еще хуже -- это вливания в собственный бизнес средств из этой самой подушки.&lt;/p&gt;

&lt;p&gt;Эта идея плоха тем, что вместо того, чтобы учиться хоть сколько-то зарабатывать на том, что уже есть, ты поддаешься соблазну вложить еще немного денег для того, чтобы &quot;довести продукт до ума&quot;. Тем самым ты лишь продлеваешь период, когда бизнес потребляет деньги, но не приносит их. И чем легче и чаще запускаешь руку в свою подушку безопасности, тем длиннее становится этот период и тем меньше шансов вернуть эти деньги впоследствии. Более вероятно, что в итоге окажешься и без бизнеса, и с совершенно голой жопой.&lt;/p&gt;

&lt;p&gt;Поэтому (в догонку к предыдущему пункту) хорошо бы иметь некий порог для подушки безопасности. Как только он достигнут, нужно прекращать эксперименты, закрывать не взлетевший бизнес и искать какой-то более реальный источник дохода.&lt;/p&gt;

&lt;p&gt;Судя по тому, что я слышал, не менее плохая идея -- это влезать в большие кредиты на поддержание своего бизнеса на плаву. К счастью, сам не проверял, но охотно верю, что так оно и есть.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Нужно как-то научиться спокойно относиться к потере собственных денег.&lt;/p&gt;

&lt;p&gt;Знаю, что звучит это утопически и сделать это гораздо сложнее, чем сказать. Особенно если ты долго работал в найме. Особенно если ты долго работал в найме на хорошей зарплате и не задумывался откуда у работодателя берутся деньги на твою ЗП.&lt;/p&gt;

&lt;p&gt;Но это как раз то, с чем придется столкнуться сразу же, особенно если в вашем бизнесе есть длительный период перед первыми продажами. Непример, когда вам нужно полгода, год, полтора года или даже больше, чтобы подготовить продукт к выходу на рынок.&lt;/p&gt;

&lt;p&gt;Вы вкладываете N собственных денег на счет вашей компании, а потом наблюдаете за тем, как эта сумма ежемесячно уменьшается. Каждый, мать его, месяц ваших денег становится все меньше и меньше, все меньше и меньше. Что особенно трудно наблюдать когда вы пробуете одно, а оно не срабатывает, потом другое, а оно тоже не срабатывает, потом третье, а оно тоже не срабатывает. Время идет, деньги тают. И это же ваши деньги тают, не чьи-то, а именно что ваши.&lt;/p&gt;

&lt;p&gt;Наблюдать за таким трудно. Тут нужно либо обзавестись достаточной степенью фатализма + здорового пофигизма, либо просто сразу закрыть лавочку и признаться самому себе, что рисковать собственными деньгами -- это не твое.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Несколько раз перечитывал текст перед публикацией и каждый раз ловил себя на том, что выступаю в роли &quot;Капитана Очевидность&quot;. Но что поделать, прописные истины не перестают быть истинами будучи повторенными в миллион сто первый раз. Приношу свои извинения за то, что не раскрыл каких-то секретных секретов.&lt;/p&gt;

&lt;p&gt;Если попытаться коротко резюмировать мой текущий опыт, то получится что-то вроде: не нужно начинать собственное дело с настроем &quot;все или ничего&quot;, намного безопаснее в стиле &quot;давайте попробуем, посмотрим что будет&quot; с четким обозначением рисков и порогов, за которые точно не стоит заходить.&lt;/p&gt;

&lt;p&gt;Я как раз сделал наоборот. Но у меня был и фактор возраста, мне было за 40 и было ощущение, что на вторую попытку меня уже не хватит (это ощущение, кстати говоря, только усиливается с возрастом). Поэтому собирал лишние грабли.&lt;/p&gt;

&lt;p&gt;Отсюда еще один, если можно так сказать, совет: не стоит затягивать с попыткой начать свое дело. Если в 35 вы задумались о том, что пора открывать что-то свое, то лучше не откладывать это до 45. Можно попробовать в 36 и к 45 совершить несколько попыток. Либо что-то увенчается успехом, либо вы поймете, что в найме все-таки спокойнее и денежнее и будете тихо встречать неизбежно приближающуюся старость ;)&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/1937138753102908269/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/1937138753102908269' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/1937138753102908269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/1937138753102908269'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/02/business.html' title='[business] Практические выводы из того, что успешный результат в бизнесе не гарантирован'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-5038592354663614404</id><published>2026-02-02T07:44:00.000+03:00</published><updated>2026-02-02T07:44:53.906+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Business"/><category scheme="http://www.blogger.com/atom/ns#" term="Поток сознания"/><title type='text'>[business] О чем вам не раскажут бизнес-спикеры с YouTube</title><content type='html'>&lt;p&gt;На новогодних выходных посмотрел на YouTube несколько роликов на тему бизнеса и YouTube начал мне подсовывать в рекомендациях подобный контент от различных бизнес-спикеров разной степени продвинутости. В подавляющем своем большинстве это что-то вроде маркетингового завлекалова, типа вот я вам сейчас расскажу о нескольких секретах, а если захотите узнать подробнее, то заходите в мой ТГ-канал или вот на этот ресурс...&lt;/p&gt;

&lt;p&gt;Не скажу, что все это абсолютно бесполезно. Встретился ряд толковых вещей, которые заставили задуматься и лучше понять что с тобой происходит и в каком месте ты сам находишься.&lt;/p&gt;

&lt;p&gt;Но практически от всего просмотренного складывается следующее ощущение: вот вам советы, следуйте им и все у вас будет зашибись.&lt;/p&gt;

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

&lt;p&gt;Почему-то мы все нормально относимся к тому, что огромное количество детей ежегодно отправляется в спортивные секции и музыкальные школы, но только малый процент из них становятся действующими спортсменами и музыкантами. И еще меньший процент достигает хоть какого-то заметного успеха в том, чем они занимаются.&lt;/p&gt;

&lt;p&gt;Можно посмотреть, скажем, на велогонщиков. В гранд-турах, вроде Вуэльты или Тур-де-Франц, участвуют порядка 200 спортсменов, но победы на этапах одерживает дай бог если пара десятков, а на общую победу даже в теории претендуют только единицы. Причем это все гонщики ТОП-ового мирового уровня, на которых приходятся тысячи тех, кто даже никогда до гранд-тура не доберется в принципе.&lt;/p&gt;

&lt;p&gt;Значит ли это, что абсолютно все те, кто не побеждает, просто недостаточно подготовлены? Что они просто мало тренируются или не соблюдают спортивный режим? Не следуют рекомендациям тренеров, спортивных врачей и других специалистов?&lt;/p&gt;

&lt;p&gt;Вовсе нет. Спорт -- это вообще такое дело, где как бы ни были сильны и заслужены соперники, победа достается кому-то одному, остальные в проигрыше.&lt;/p&gt;

&lt;p&gt;Мы все с этим прекрасно знакомы. Поэтому нас не удивляет, что в том же спорте пытаются многие, но подавляющее их большинство сходит с дистанции, некоторые и по независящим от них причинам. Например, из-за травм. Т.е. даже при наличии таланта, целеустремленности и большого труда все равно можно распрощаться со своей мечтой из-за стечения обстоятельств или чьей-то ошибки.&lt;/p&gt;

&lt;p&gt;Поэтому когда кто-то приходит в спорт, то все прекрасно отдают себе отчет, что нужен и талант, и работоспособность, и правильные методики, и подходящий тренер, и пятое, и десятое. Но все равно нет никаких гарантий того, что спустя 10-15-20 лет упорных занятий спортсмена ждет заслуженная победа.&lt;/p&gt;

&lt;p&gt;Но когда речь заходит о бизнесе, то почему-то нам пытаются продать совсем другую картину мира: мол, есть набор волшебных рекомендаций, типа правильно все рассчитай, упорно работай, не совершай ошибок и тебя ждет успех. Успешный успех, как же иначе.&lt;/p&gt;

&lt;p&gt;Ага. Как же.&lt;/p&gt;

&lt;p&gt;Прошу понять меня правильно. Я не пытаюсь доказать читателям, что если вы попытаетесь начать свой бизнес, то вас обязательно ждет неудача. И уж тем более не отговариваю от этой затеи.&lt;/p&gt;

&lt;p&gt;Всего лишь хочу сказать, что неудачи в бизнесе -- это как проигрыше в спорте. Нормальное явление. Обыденное даже. Поэтому идти в бизнес с установкой &quot;у меня обязательно все получится&quot;, как по мне, это тоже самое, как идти в спорт с уверенностью в том, что никогда не проиграешь.&lt;/p&gt;

&lt;p&gt;Ну и как в спорте, важно не сколько раз ты упал, а сколько раз поднялся.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/5038592354663614404/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/5038592354663614404' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/5038592354663614404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/5038592354663614404'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/02/business-youtube.html' title='[business] О чем вам не раскажут бизнес-спикеры с YouTube'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-5766568402180260337</id><published>2026-02-01T15:35:00.000+03:00</published><updated>2026-02-01T15:35:40.220+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Кино"/><category scheme="http://www.blogger.com/atom/ns#" term="О жизни"/><category scheme="http://www.blogger.com/atom/ns#" term="Ссылки"/><title type='text'>[life.cinema] Очередной кинообзор (2026/01)</title><content type='html'>&lt;p&gt;Подошло время традиционного отчета о просмотренных за минувший месяц фильмах. Традиционно в начале каждого из списков идет то, что понравилось больше. Хотя в данном случае лучше бы сказать, что в начале списков то, что разочаровало меньше. Тогда как завершаются списки тем, на что я бы не советовал тратить время вообще. Однако, из всего описанного ниже &quot;Чудовище внутри меня&quot; вполне заслуживает внимания.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Фильмы&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/6398494/&quot;&gt;Лакомый кусок (The Rip, 2025)&lt;/a&gt;. Смотрибельно. Но по ходу всего фильма не мог отделаться от ощущения, что диалоги какие-то странные: о чем-то персонажи говорят, но какой-то связности, целостности и последовательности не ощущается. Может быть проблема в переводе.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/4421816/&quot;&gt;Достать ножи: Воскрешение покойника (Wake Up Dead Man, 2025)&lt;/a&gt;. Гораздо лучше, чем вторая часть, вполне можно смотреть. Но для меня здесь слишком много театральщины и пафоса, что сильно портит впечатление.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/7029912/&quot;&gt;Голосовой помошник (2025)&lt;/a&gt;. В общем смотрибельно. Но лично для меня авторы фильма не смогли создать атмосферу, в которой бы в происходящее верилось бы.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/6459560/&quot;&gt;Опасный дуэт (The Wrecking Crew, 2026)&lt;/a&gt;. Не понравилось. Была всего одна или две приличных экшен-сцен, все остальное какая-то скучная муть. Ну и 50-летние дядьки, которые играют 25-летних малолетних дебилов смотрятся еще большими дебилами, чем их герои.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/8613332/&quot;&gt;Джентльмен (Ya No Quedan Junglas, 2025)&lt;/a&gt;. Откровенная халтура, смело можно не смотреть.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Сериалы&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/9167314/&quot;&gt;Чудовище внутри меня (The Beast in Me, первый сезон, 2025)&lt;/a&gt;. Очень даже ничего. Не могу сказать, что прям &quot;Вау!&quot;, но сюжет хороший, не затянуто, отличная игра актеров. Даже гомосексуальная повестка, которую сюда впихнули, в принципе, оказалась оправдана.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/5939529/&quot;&gt;Злые люди (первый сезон, 2025)&lt;/a&gt;. Очень посредственно. Все очень лубочное и все персонажи какие-то картонные, безжизненные.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/6553393/&quot;&gt;Задание (Task, первый сезон, 2025)&lt;/a&gt;. Криминальная составляющая вполне себе ничего, можно было бы и посмотреть, если бы ее уместили в 3 серии. Но вот семейная драма главного героя, как по мне, так вообще абсолютно лишняя и ничего стоящего к происходящему не добавляет, без всех этих соплей можно было бы и обойтись.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/5766568402180260337/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/5766568402180260337' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/5766568402180260337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/5766568402180260337'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/02/lifecinema-202601.html' title='[life.cinema] Очередной кинообзор (2026/01)'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-4796814196093413435</id><published>2026-01-26T07:15:00.002+03:00</published><updated>2026-01-26T07:15:45.002+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Из непонятого"/><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="Поток сознания"/><title type='text'>[prog.thoughts] Как ИИ может отбирать хлеб у разработчиков библиотек</title><content type='html'>&lt;p&gt;Сразу хочу жирный disclaimer: я не утверждаю, что сказанное мной ниже уже является реальностью. Но есть ощущение, что к этому идет. Буду только рад, если в итоге ошибусь.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Еще десять лет назад у разработчиков OpenSource продуктов была такая опция для монетизации своей работы как платные консультации и платное обучение. Грубо говоря, есть открытая библиотека X за которой стоит компания Y. И если вы не можете разобраться с X самостоятельно, то обращаетесь к Y за помощью, а Y направляет к вам людей, которые учат вас, отвечают на ваши вопросы и подсказывают вам какие-то решения, которые вы не видите в силу своего незнания X.&lt;/p&gt;

&lt;p&gt;Сейчас же большинство вопросов по любой OpenSource-библиотеке можно решить посредством того или иного ИИ-инструмента. Соответственно, нет надобности обращаться за помощью к разработчиками. А раз так, то и платные консультации/обучения отмирают за ненадобностью.&lt;/p&gt;

&lt;p&gt;Грубо говоря, если 10 лет назад я рассчитывал на то, что вокруг OpenSource можно зарабатывать на трех вещах:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;платная поддержка и оперативное устранение проблем для тех клиентов, которые готовы за это платить;&lt;/li&gt;
  &lt;li&gt;кастомизация под нужды конкретного клиента, возможно даже с созданием закрытого форка;&lt;/li&gt;
  &lt;li&gt;платные консультации и обучение.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;То теперь бы из этого перечня я бы платные консультации и обучение вычеркнул. Это не значит, что такого не может быть. Но подобные вещи будут эпизодическими и закладывать их в бизнес-модель я бы не стал.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Чтобы затронуть еще один важный момент нужно ответить на вопрос, а зачем вообще нужны библиотеки?&lt;/p&gt;

&lt;p&gt;На мой взгляд, библиотеки упрощают решение конкретных задач. Например, библиотека для работы с файловой системой позволяет нам получать списки файлов, удалять и переименовывать файлы, устанавливать текущий каталог и т.д. Библиотека для файлового ввода/вывода позволяет нам читать и записывать содержимое файлов. Библиотека для работы с форматом JSON позволяет нам получать данные из JSON-представления или преобразовывать данные в JSON-представление. И т.д., и т.п.&lt;/p&gt;

&lt;p&gt;Почему библиотеки возникли?&lt;/p&gt;

&lt;p&gt;Потому, что неэффективно заставлять программистов снова и снова выписывать повторяющиеся строки кода для выполнения одних и тех же действий.&lt;/p&gt;

&lt;p&gt;Но эта неэффективность возникала из-за того, что программисты писали код вручную. И требовалось найти какой-то способ переиспользования сделанного ранее не впадая в тотальную копипасту. В итоге пришли к библиотекам.&lt;/p&gt;

&lt;p&gt;Однако, времена изменились. ИИ-евангелисты предсказывают, что человек будет писать промпты, а не код. Код же будет генерироваться ИИ-шками из промптов. И что там будет творится в этом сгенерированном коде уже не важно (по заверениям тех же ИИ-евангелистов).&lt;/p&gt;

&lt;p&gt;Возможно это приведет к тому, что библиотеки отживут свое как явление.&lt;/p&gt;

&lt;p&gt;Действительно, зачем нужна удобная библиотека для парсинга JSON-а, если ИИ по спецификации может сгенерировать фрагмент, который будет разбирать входной поток байт прямо &quot;по месту&quot;? Кого вообще будет заботить, что ИИ сгенерировал &quot;рукопашный&quot; разбор вместо того, чтобы использовать готовую JSON-библиотеку? Особенно, если сгенерированный код справляется со своими задачами и покрыт тестами (сгенерированными тем же ИИ).&lt;/p&gt;

&lt;p&gt;До сих пор мы жили в мире, где у нас был лишь самый базовый набор относительно низкоуровневых инструментов. Например, доступ к API операционной системы и (возможно скудные) средства стандартной библиотеки конкретного языка программирования. На базе которых создавались более высокоуровневые средства (библиотеки и фреймворки) с помощью которых прикладные программисты уже решали конкретные задачи пользователей.&lt;/p&gt;

&lt;p&gt;И чем лучше и удобнее были те самые библиотеки, тем проще было прикладным программистам.&lt;/p&gt;

&lt;p&gt;Но сейчас результат вполне можно будет получать и без всех этих промежуточных инструментов. Т.е. опираясь только на API операционной системы и средства стандартной библиотеки языка программирования ИИ может генерировать все, что нужно: от парсинга аргументов командной строки до координации распределенных транзакций.&lt;/p&gt;

&lt;p&gt;Поэтому есть ощущение, что написанные людьми библиотеки, устраняющие рутину или переводящие работу на другой уровень абстракции, становятся не нужны. Они могут быть заменены на сгенерированный ИИ код. А значит и может отпасть и надобность в самих разработчиках библиотек. И, как следствие, в услугах тех, кто эти библиотеки писал раньше, в старые добрые времена.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/4796814196093413435/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/4796814196093413435' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/4796814196093413435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/4796814196093413435'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/01/progthoughts.html' title='[prog.thoughts] Как ИИ может отбирать хлеб у разработчиков библиотек'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-2865132199908684092</id><published>2026-01-20T09:23:00.001+03:00</published><updated>2026-01-21T07:41:13.323+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="Поток сознания"/><title type='text'>[prog.flame] Пробелы таки выигрывают у табуляции?</title><content type='html'>&lt;p&gt;На протяжении многих лет был приверженцем табуляций в исходных текстах. Хотя начинал, конечно же, с пробелов. Просто потому, что изначально даже не знал про существование табуляции 😀&lt;/p&gt;

&lt;p&gt;А вот когда узнал, году эдак в 1992-ом, то практически сразу же перешел с пробелов на табуляции, ибо:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;исходные файлы с табуляцией занимали гораздо меньше места. Что было более чем критично во времена дискет на 1.2 MiB. Ведь тогда в наших палестинах самыми распространенными были 5.25&quot; дисководы и дискеты на 360 KiB, 720 KiB и 1.2 MiB (хотя не везде диски на 1.2 MiB нормально читались и писались). Гораздо более надежные и практичные 3.5&quot; дискеты на 1.44 MiB в нашей местности получили распространение спустя несколько лет. Архиваторы, вроде pkzip и arj уже были, но вроде бы исходники с пробелами все равно сжимались хуже;&lt;/li&gt;

  &lt;li&gt;текстовые редакторы для программистов тогда были гораздо более убогими, чем сейчас. Я не припомню редакторов, которые бы по клавише Tab и по сочетанию Shift+Tab двигали бы выделенный блок текста вправо или влево. Поэтому если тебе нужно было изменить выравнивание куска кода, то приходилось делать это вручную, и с табами было это гораздо быстрее и проще;&lt;/li&gt;

  &lt;li&gt;в те времена достаточно распространенной практикой была распечатка текстов программ. Сейчас это кажется диким, а 35 лет назад машинное время было дефицитом и ты не мог сидеть за компьютером часами на пролет в поиске какого-то заковыристого бага -- тебе этого просто не позволяли, а собственных персональных IBM PC-совместимых компьютеров в те времена практически ни у кого не было. В текстовом редакторе можно было выставить размер табуляции в 2 символа и видеть больше на тогдашних 14&quot; EGA/VGA экранах с текстовым режимом 80x25 символов, а для печати использовать размер в 4 символа и получать более удобный для чтения формат. Тогда как с пробелами такой фокус уже не проходил.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;В общем, в начале 1990-х для меня табы были намного практичнее пробелов. И таковыми они оставались в течении тридцати лет. Но сейчас ситуация в моих сценариях работы сильно изменилась.&lt;/p&gt;

&lt;p&gt;Во-первых, теперь постоянно приходится пользоваться сервисами, в которых я не могу поменять размер табуляции (ну или не знаю как это сделать). Самый яркий пример -- вводишь в консоли команду git diff и git разворачивает табуляцию на 8 пробелов. Или вводишь пример кода в какой-нибудь Wiki-системе и результирующая Web-страничка заменяет табуляцию на столько пробелов, сколько ей вздумается. Получается, что ты копипастишь кусок кода из своего редактора, где все прекрасно помещается в 80 символов по ширине, но на Web-ресурсе этот же фрагмент может получиться настолько широким, что выползет за край видимой области.&lt;/p&gt;

&lt;p&gt;Во-вторых, мне по работе периодически приходится вставлять куски кода в e-mail-ы или документы Google.Doc. Типа вот есть такой фрагмент, в нем вот здесь и вот здесь есть вот такие и такие проблемы, исправить их можно вот так и вот так, а еще лучше было бы переписать вот так или вот так. Но, к сожалению, со вставкой кусков кода с табуляцией внутри могут возникнуть проблемы. Так, если я пишу письмо прямо в Web-интерфейсе Google Mail, то при отправке письма все табы вырезаются и форматирование кода оказывается полностью сломано -- весь текст просто прижимается к левому краю 😡
Если фрагмент вставляется в Google.Doc, то форматирование более-менее сохраняется, но вносить в такой фрагмент правки -- это то еще приключение.&lt;/p&gt;

&lt;p&gt;Вообще когда набираешь или редактируешь какой-то кусок кода в многострочном редакторе на Web-форме (что часто происходит при работе с Wiki-системами), то нажатие на Tab, как правило, выбрасывает тебя из редактора вообще. Т.е. если ты скопировал фрагмент с табуляциями и хочешь расширить этот фрагмент дописав туда что-нибудь, то вставить новые строки с табами внутри будет не так-то просто.&lt;/p&gt;

&lt;p&gt;В итоге получается, что в современном мире гораздо проще использовать пробелы для форматирования исходного кода:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;место на диске уже не проблема,&lt;/li&gt;
  &lt;li&gt;редакторы для программистов намного более продвинутые (+ часто используется автоформатирование),&lt;/li&gt;
  &lt;li&gt;исходные тексты уже практически никогда не приходится печатать на бумаге.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Преимуществ у табов, по факту, не осталось. Кроме привычки. Зато код с пробелами везде выглядит одинаково и забот с пробелами намного меньше.&lt;/p&gt;

&lt;p&gt;Все вышесказанное не означает, что я вот прям взял и побежал менять табы на пробелы в своих проектах. Нет, в старом коде табы пусть продолжают жить как жили.&lt;/p&gt;

&lt;p&gt;А вот для новых проектов, похоже, имеет смысл выбирать именно пробелы.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/2865132199908684092/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/2865132199908684092' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2865132199908684092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2865132199908684092'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/01/progflame.html' title='[prog.flame] Пробелы таки выигрывают у табуляции?'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-2438944047124568379</id><published>2026-01-02T11:35:00.000+03:00</published><updated>2026-01-02T11:35:38.016+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Кино"/><category scheme="http://www.blogger.com/atom/ns#" term="О жизни"/><category scheme="http://www.blogger.com/atom/ns#" term="Ссылки"/><title type='text'>[life.cinema] Очередной кинообзор (2025/12)</title><content type='html'>&lt;p&gt;Отчет о просмотренных в декабре фильмах. По традиции в начале каждого из списков идет то, что понравилось больше. Хотя сразу скажу, что в списке сериалов ничего понравившегося нет :(&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Фильмы&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/5501397/&quot;&gt;Первый на Олимпе (2025)&lt;/a&gt;. Мог бы получиться просто отличный фильм, если бы не главный злодей, которого сделали настолько злодейским, что прям караул.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/1378893/&quot;&gt;Бугония (Bugonia, 2025)&lt;/a&gt;. Очень необычное кино. И посмотреть его можно только из-за того, что это очень необычное кино. Но нужно перетерпеть первые 2/3 фильма, т.к. все самое интересное начинается именно в конце.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/979438/&quot;&gt;Грабитель с крыши (Roofman, 2025)&lt;/a&gt;. Хорошее и доброе кино.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/5354707/&quot;&gt;Годзила: минус один (Gojira -1.0)&lt;/a&gt;. Весьма неплохо. Снято за копейки, но в подавляющем большинстве случаев все деньги реально видны на экране (за редким исключением). Если бы не азиатская актерская школа, когда истерики доведены до максимума, так было бы просто зашибись.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/5437094/&quot;&gt;Битва за битвой (One Battle After Another, 2025)&lt;/a&gt;. Вот вообще не понял что это было. В меня кино совершенно не попало. И еще я не понял, почему считается, что главная звезда в этом фильме ДиКаприо, как по мне, так все держится на Шоне Пенне.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/4387862/&quot;&gt;Бегущий человек (The Running Man, 2025)&lt;/a&gt;. Редкий бред и редкий тупизм. Но бодренько, да.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Сериалы&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/1137755/&quot;&gt;Разведчик (The Spy, первый сезон, 2019)&lt;/a&gt;. Сериальная затянутость в худшем смысле этого слова. Как по мне, эту же историю можно было бы уместить в три серии.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/6012599/&quot;&gt;Одна из многих (Pluribus, первый сезон, 2025)&lt;/a&gt;. Начало прикольное, первые две серии смотрятся на одном дыхании. Потом как будто у авторов запал пропадает и повествование превращается в унылую скукоту. Ну а вишенкой на торте то, что никакой развязки нет -- чисто замануха для последующих сезонов.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/1291310/&quot;&gt;В её глазах (Behind Her Eyes, первый сезон, 2021)&lt;/a&gt;. Смело можно было бы сократить хронометраж раза в два. Тогда бы могло получиться что-то достойное. А так нудная нудятина, да еще и основной твист угадывается еще в предпоследней серии.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/7400477/&quot;&gt;Тоннель (первый сезон, 2025)&lt;/a&gt;. Какой-то сказочный мир в котором какие-то сказочные персонажи творят какую-то сказочную хрень. Смело можно не смотреть.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/6601549/&quot;&gt;Последний рубеж (The Last Frontier, первый сезон, 2025)&lt;/a&gt;. Смотреть можно разве что для того, чтобы подсчитывать количество раз, когда ты воскликнешь &quot;ну что за бред?!&quot;. А если серьезно, то лучше пройти мимо и не тратить свое время.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;В качестве итогов 2025-го года из фильмов я бы выделил &lt;a href=&quot;https://www.kinopoisk.ru/film/5003510/&quot;&gt;F1 (2025)&lt;/a&gt; и &lt;a href=&quot;https://www.kinopoisk.ru/film/4477141/&quot;&gt;Маскарад (Mascarade, 2022)&lt;/a&gt;, а из сериалов &lt;a href=&quot;https://www.kinopoisk.ru/series/5333424/&quot;&gt;Бар &quot;Один звонок&quot; (первый сезон, 2023)&lt;/a&gt;, &lt;a href=&quot;https://www.kinopoisk.ru/series/6589776/&quot;&gt;Больница Питт (The Pitt, 2025)&lt;/a&gt;, &lt;a href=&quot;https://www.kinopoisk.ru/series/5436748/&quot;&gt;13 клиническая. Начало (2024)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Отдельно бы отметил пару свежих глотков воздуха во вселенной &quot;Хищника&quot;. Прежде всего полнометражный мультфильм &lt;a href=&quot;https://www.kinopoisk.ru/film/7596122/&quot;&gt;Хищник: Убийца убийц (Predator: Killer of Killers, 2025)&lt;/a&gt;. Но и кино &lt;a href=&quot;https://www.kinopoisk.ru/film/5463792/&quot;&gt;Хищник: Планета смерти (Predator: Badlands, 2025)&lt;/a&gt; лично мне очень понравилось.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/2438944047124568379/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/2438944047124568379' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2438944047124568379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/2438944047124568379'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2026/01/lifecinema-202512.html' title='[life.cinema] Очередной кинообзор (2025/12)'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-80275477908580797</id><published>2025-12-31T11:24:00.000+03:00</published><updated>2025-12-31T11:24:01.698+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Humour"/><category scheme="http://www.blogger.com/atom/ns#" term="О жизни"/><category scheme="http://www.blogger.com/atom/ns#" term="О работе"/><title type='text'>[work-n-life] Послесловие к уходящему году и поздравления с НГ</title><content type='html'>&lt;p&gt;Решил в этом году повторить &lt;a href=&quot;https://eao197.blogspot.com/2024/12/work-n-life.html&quot;&gt;итоговый пост из 2024-го&lt;/a&gt; С точно такой же мотивацией -- за последние недели лента в LinkedIn вновь превратилась в какую-то приторную выставку тщеславия с лубочными постами достигаторов успешного успеха. Поэтому напишу простой и приземленный пост о том, как оно, у простых смертных.&lt;/p&gt;

&lt;p&gt;Уходящий год для меня внезапно и без предварительного предупреждения стал годом болезней и плотного знакомства с больницами. В общей сложности на все это ушло три месяца. К счастью, клиенты отнеслись к происходящему с большим пониманием и безграничным терпением, за что им огроменное спасибо.&lt;/p&gt;

&lt;p&gt;Пребывание в больнице предоставляет кучу времени для размышлений о том, на что уходит твое время и на что бы ты хотел потратить остаток своей жизни. Саморефлексия на эту тему позволила сформулировать некоторый вывод, который имеет самое непосредственное отношение к работе. Может быть соберусь с силами и напишу на эту тему подробнее.&lt;/p&gt;

&lt;p&gt;В профессиональном плане, когда здоровье позволяло полноценно работать, все было достаточно ровно и рутинно, как и в 2024-ом: получаешь новую задачу, вникаешь, куришь бамбук, экспериментируешь, делаешь, тестируешь, доводишь до ума, получаешь новую задачу, вникаешь, куришь бамбук... И так снова и снова. Разве что местами сложность выполняемой работы несколько превышала мои возможности и мозги закипали от нагрузки. Очень надеюсь, что так продолжится и в 2026-ом.&lt;/p&gt;

&lt;p&gt;С другой стороны, 2025-ый оказался все таким же безрадостным для наших собственных открытых продуктов. Два небольших релиза для SObjectizer и ничего нового в RESTinio 🙁
Но нельзя не вспомнить два знаковых события, связанных с SO-5: &lt;a href=&quot;https://www.linkedin.com/posts/eao197_%D0%BD%D0%B0-%D0%B4%D0%BD%D1%8F%D1%85-%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%BE%D1%88%D0%BB%D0%BE-%D1%8F-%D0%B1%D1%8B-%D1%81%D0%BA%D0%B0%D0%B7%D0%B0%D0%BB-%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5-activity-7382262655736201216-yexS&quot;&gt;доклад Марко Арена на митапе в Болонье&lt;/a&gt; и &lt;a href=&quot;https://eao197.blogspot.com/2025/12/progc-yadro-sobjectizer.html&quot;&gt;использование SO-5 в проекте компании YADRO&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;По поводу SObjectizer-а есть одна большая хотелка на 2026-й и было бы очень и очень здорово, если бы удалось воплотить её в жизнь.&lt;/p&gt;

&lt;p&gt;В блог писал меньше, чем в предыдущие годы. Даже в самом тяжелом 2021-ом удалось написать на один пост больше. Отчасти это объясняется тем, что сейчас я гораздо чаще сиюминутные впечатления публикую &lt;a href=&quot;http://www.linkedin.com/in/eao197/&quot;&gt;в LinkedIn&lt;/a&gt;. В этом плане использую LinkedIn в качестве Twitter-а -- удобно зафиксировать какую-то эмоцию или сделать репост чего-то. Тогда как написание блог-поста требует времени и концентрации, поэтому на blogger-е публиковался меньше. Но старался не снижать качества. Чем, собственно, и собираюсь заниматься в следующем году. Так что если вы все еще находите для себя что-то интересное в моем блоге, то не переключайтесь 😉&lt;/p&gt;

&lt;p&gt;Ну а вне работы ничего интересного не было вообще. Может быть за исключением знакомства с парой новых динамиков с Aliexpress, о чем постараюсь рассказать отдельно через месяц-другой, когда остальные покупки приедут. Бюджетная аудиофилия, к сожалению, все еще со мной 🥴&lt;/p&gt;

&lt;p&gt;Планы на будущий год опять очень простые: прожить его.&lt;/p&gt;

&lt;p&gt;Только вот в 2025-ом воплотить их в жизнь оказалось не так-то просто. Надеюсь, в 2026-ом будет попроще. И, если это получится, то буду стараться делать что-то полезное и публиковать что-нибудь интересное. Как-то так.&lt;/p&gt;

&lt;p&gt;Всем же читателям пожелаю здоровья, здоровья и еще раз здоровья в наступающем 2026-ом. Пусть ваш 2026-ой будет гораздо лучше моего 2025-го.&lt;/p&gt;

&lt;p&gt;Ну и всем нам мирного неба над головой.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;PS. Немного слукавил по поводу отсутствия чего-либо интересного вне работы: в этом году случилось 30-летие нашего выпуска из ГГУ. На вечер встречи мне прийти не удалось, но зато раскопал свои старые фотопленки со студенческих времен и оцифровал то, что на них еще осталось. Заглянуть в прошлое на несколько десятков лет назад -- это впечатляет. Вот, например, ваш покорный слуга собственной персоной в кузове трактора &quot;на картошке&quot; в октябре 1990-го года.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh0eZ4um5BN31zhrIwyAU54kDMba9UkjgqSFqkpHIx7uwDrR5-9VXoTQQfdDQhjN1Ob6_tEpmkP5IgPV45EYt3cm5J0U6njSqeANs4I-WcV2Jz9CeMab9jMqQx2r06tSh4EYrZyDBRh84unLt6L7XS2hsjZXKksYhOu-VFRN2BkkUggfoW0QR7SyNEMvQ/s3000/%D0%A4%D0%BE%D1%82%D0%BE_%D1%81_%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D1%88%D0%BA%D0%B8_%D0%BE%D0%BA%D1%82%D1%8F%D0%B1%D1%80%D1%8C_1990.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;600&quot; data-original-height=&quot;1914&quot; data-original-width=&quot;3000&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh0eZ4um5BN31zhrIwyAU54kDMba9UkjgqSFqkpHIx7uwDrR5-9VXoTQQfdDQhjN1Ob6_tEpmkP5IgPV45EYt3cm5J0U6njSqeANs4I-WcV2Jz9CeMab9jMqQx2r06tSh4EYrZyDBRh84unLt6L7XS2hsjZXKksYhOu-VFRN2BkkUggfoW0QR7SyNEMvQ/s600/%D0%A4%D0%BE%D1%82%D0%BE_%D1%81_%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D1%88%D0%BA%D0%B8_%D0%BE%D0%BA%D1%82%D1%8F%D0%B1%D1%80%D1%8C_1990.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/80275477908580797/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/80275477908580797' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/80275477908580797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/80275477908580797'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2025/12/work-n-life.html' title='[work-n-life] Послесловие к уходящему году и поздравления с НГ'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh0eZ4um5BN31zhrIwyAU54kDMba9UkjgqSFqkpHIx7uwDrR5-9VXoTQQfdDQhjN1Ob6_tEpmkP5IgPV45EYt3cm5J0U6njSqeANs4I-WcV2Jz9CeMab9jMqQx2r06tSh4EYrZyDBRh84unLt6L7XS2hsjZXKksYhOu-VFRN2BkkUggfoW0QR7SyNEMvQ/s72-c/%D0%A4%D0%BE%D1%82%D0%BE_%D1%81_%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D1%88%D0%BA%D0%B8_%D0%BE%D0%BA%D1%82%D1%8F%D0%B1%D1%80%D1%8C_1990.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-209629656830845232</id><published>2025-12-30T15:31:00.000+03:00</published><updated>2025-12-30T15:31:40.638+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SObjectizer"/><category scheme="http://www.blogger.com/atom/ns#" term="Воспоминания"/><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Двадцать лет назад была опубликована первая статья о SObjectizer</title><content type='html'>&lt;p&gt;30-го декабря 2005-го года в печатном(!!!) номере журнала RSDN Magazine (ага, был такой) вышла статья &lt;a href=&quot;https://rsdn.org/article/devtools/sobjectizer.xml&quot;&gt;SObjectizer: I Love This Game!&lt;/a&gt;. В ней впервые описывался SObjectizer-4 из которого в 2010-ом вырос и нынешний SObjectizer-5.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRYpUuCY_SAbBvdJEcsPRe6lXv_KPzMDHeVUsCZIgGz0M-noGw1ajtyYrO9cHoTWU6DiEQYA1qcZj5WPqmGdtU23-oPFDs4akQzJ_fBhbrgLCjXHgXWAyFVAvN77QuN5ogsBWrw7RojFMt7cp5VnP2mYNDNvQG1rza_CeqGrX8jCgEkeJ5ZcfkfgzksQw/s4146/RSDN_Mag_2005_4.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;600&quot; data-original-height=&quot;4146&quot; data-original-width=&quot;3177&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRYpUuCY_SAbBvdJEcsPRe6lXv_KPzMDHeVUsCZIgGz0M-noGw1ajtyYrO9cHoTWU6DiEQYA1qcZj5WPqmGdtU23-oPFDs4akQzJ_fBhbrgLCjXHgXWAyFVAvN77QuN5ogsBWrw7RojFMt7cp5VnP2mYNDNvQG1rza_CeqGrX8jCgEkeJ5ZcfkfgzksQw/s600/RSDN_Mag_2005_4.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Сейчас самому очень интересно читать про SO-4.&lt;/p&gt;

&lt;p&gt;Во-первых, все уже основательно забыто, читаешь как про незнакомый для тебя проект. И при этом забавно находить какие-то привычные по SO-5 вещи.&lt;/p&gt;

&lt;p&gt;Во-вторых, не верится, что это все писал ты сам. Только на 20 лет моложе и гораздо более уверенный и в своих силах, и в своих решениях.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir4UnFduXwF7OUDiC7NXauBw3c_e0393-Io_-ovyscirC524nNfcJ93Uu7RaE_e1CNfgqF0ISmuOj7Ivi6rei3nIs_K-ydLlNO3yS1LMd9K-CfhLhHlhwxW9F19HHItscbTVvdlNfbbmrk4Vv09kQEBYs-ONrFAtu_lyV0qVHcQExUFJAoYZAEoQZIlrU/s4280/RSDN_Mag_2005_4_Article.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;600&quot; data-original-height=&quot;3456&quot; data-original-width=&quot;4280&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir4UnFduXwF7OUDiC7NXauBw3c_e0393-Io_-ovyscirC524nNfcJ93Uu7RaE_e1CNfgqF0ISmuOj7Ivi6rei3nIs_K-ydLlNO3yS1LMd9K-CfhLhHlhwxW9F19HHItscbTVvdlNfbbmrk4Vv09kQEBYs-ONrFAtu_lyV0qVHcQExUFJAoYZAEoQZIlrU/s600/RSDN_Mag_2005_4_Article.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Через некоторое время после публикации этой статьи исходные тексты SO-4 были размещены на SourceForge и SObjectizer перешел в категорию OpenSource проектов. Что и определило его дальнейшую судьбу. Ведь благодаря тому, что в 2006-ом открыли SO-4, в 2013-ом был открыт и SO-5. А это позволило нам продолжить работать над SO-5 и после ухода из компании Интервэйл, где SObjectizer появился. Не случись той первой статьи о SObjectizer, возможно и SO-4, и SO-5 так и остались бы внутренними проектами компании. И, скорее всего, тихо бы умерли с годами в связи закрытием проектов, в которых SObjectizer использовался.&lt;/p&gt;

&lt;p&gt;Более того, не случись первой статьи о SO-4, возможно, никакого бы SO-5 и не появилось бы вовсе. В процессе обсуждения SObjectizer-а в Интернете (в первую очередь вспоминаются диалоги с Дмитрием Вьюковым) стало понятно, что SO-4 достиг своего потолка, что его возможности по развитию полностью исчерпаны, что нужно делать новую итерацию, оставив самое важное, но исправив допущенные ошибки.&lt;/p&gt;

&lt;p&gt;На осмысление всего этого требовалось время. Но, в итоге, в 2010-ом разработка SO-5 стартовала. И, к счастью, продолжается до сих пор. Что вряд ли произошло бы без той самой &quot;SObjectizer: I Love This Game!&quot; в декабре 2005-го.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Пока писал эти строки поймал себя на том, что одной из причин, по которой SO-4 не вызвал интереса в 2005-ом, была роль C++ в тогдашнем ИТ. Прекрасно помню, как C++ тогда стремительно превращался из мейнстрима в маргинальный язык, который принято ругать и ни в коем случае нельзя брать для разработки.&lt;/p&gt;

&lt;p&gt;Спустя 20 лет как будто все тоже самое: С++ -- это тот самый язык, который принято ругать и ни в коем случае нельзя брать для разработки. Если, конечно, слушать всяких экспертных экспертов в Интернете 😁&lt;/p&gt;

&lt;p&gt;Только 20 лет назад предлагали валить с C++ на Java и C#. А сейчас с C++ на Go или Rust. Но валить надо, хоть в этом есть какая-то стабильность 😏&lt;/p&gt;

&lt;p&gt;Что уж поделать, реальность такова, что мы пишем код на C++, живем с недостатками C++ и делаем инструмент, упрощающий нам жизнь именно с C++. Работай мы на Java, C# или Rust-е, возможно, сделали бы что-то вроде SObjectizer-а и для этих языков. Но выглядело бы это точно иначе. А пока мы продолжаем программировать на C++, то и SObjectizer остается на C++ и для C++. Се ля ви.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Если же продолжить тему юбилеев (а ведь в 2025-ом &lt;a href=&quot;https://eao197.blogspot.com/2025/11/progc-sobjectizer-5.html&quot;&gt;исполнилось 15 лет пятому SObjectizer-у&lt;/a&gt;), то самим идеям, которые легли в основу сперва SCADA Objectizer, а затем и SObjectizer, уже лет тридцать. Если мне не изменяет склероз, то сформулированы они были осенью 1995-го года.&lt;/p&gt;

&lt;p&gt;Дело было так. В октябре 1994-го меня и еще двух моих друзей-сокурсников пригласил работать в свой отдел в КБ Системного Программирования Аркадий Косарев. Как раз для того, чтобы нашими силами делать новую объектно-ориентированную SCADA-систему. И вот с осени 1994-го по весну 1995-ого мы будучи студентами пятого курса + еще один наш молодой коллега, Василий Гайдуков (он закончил наш же универ на год раньше), пытались родить какие-то идеи для будущей SCADA-системы. Без особого успеха, что было вполне ожидаемо.&lt;/p&gt;

&lt;p&gt;Но в 1995-ом в наш отдел пришел Андрей Лабыч и с лета 1995-го работы над новой SCADA-системой получили мощный толчок. Главным образом усилиями Андрея Лабыча. Помнится, именно он сформулировал основные принципы: система строится из именованных агентов, агенты обслуживаются диспетчером, обмениваются информацией друг с другом только посредством именованных сообщений, для получения сообщения нужно подписаться на сообщение, а реакция на сообщения зависит от текущего состояния агента, при этом в каждом состоянии могут быть свои уникальные подписки, а если агент не имеет подписки на сообщение в своем текущем состоянии, то сообщение выбрасывается.&lt;/p&gt;

&lt;p&gt;Как именно рождались идеи SCADA Objectizer я уже не помню, но вспоминается, что большее влияние оказала книга &quot;Объектно-ориентированный анализ: моделирование мира в состояниях&quot; за авторством С.Шлеер и С.Меллор.&lt;/p&gt;

&lt;p&gt;Не помню и когда именно появилось само название SCADA Objectizer. Почему-то кажется, что позже, году в 1997-ом, если не в 1998-ом. Но вот в том, что базовые принципы будущего SCADA Objectizer-а были сформулированы осенью 1995-го или зимой 1996-го практически уверен. &lt;/p&gt;

&lt;p&gt;В общем, как-то очень уж долго я варюсь в этой теме агентов, асинхронно общающихся друг с другом посредством сообщений. Но, тем не менее, все еще love this game! Отличный все-таки был выбран заголовок для статьи 20 лет назад. До сих пор актуальный.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;В Интернете все еще валяется руководство по программированию на SObjectizer-4 под скромным названием &lt;a href=&quot;https://eao197.narod.ru/desc/so_4_book.pdf&quot;&gt;SObjectizer-4 Book&lt;/a&gt; 😲&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/209629656830845232/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/209629656830845232' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/209629656830845232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/209629656830845232'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2025/12/progc-sobjectizer.html' title='[prog.c++] Двадцать лет назад была опубликована первая статья о SObjectizer'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRYpUuCY_SAbBvdJEcsPRe6lXv_KPzMDHeVUsCZIgGz0M-noGw1ajtyYrO9cHoTWU6DiEQYA1qcZj5WPqmGdtU23-oPFDs4akQzJ_fBhbrgLCjXHgXWAyFVAvN77QuN5ogsBWrw7RojFMt7cp5VnP2mYNDNvQG1rza_CeqGrX8jCgEkeJ5ZcfkfgzksQw/s72-c/RSDN_Mag_2005_4.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-5438273199154064215</id><published>2025-12-26T16:06:00.000+03:00</published><updated>2025-12-26T16:06:26.083+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SObjectizer"/><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="Хвастаюсь"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Компания YADRO использует SObjectizer в одном из своих проектов</title><content type='html'>&lt;p&gt;Поскольку информация об этом &lt;a href=&quot;https://itgorky.ru/article/ot-sprinta-do-stancii-kak-rabotaet-komandakotoraja-sozdala-platformu-dlja-bazovihkh-stanciy-yadro&quot;&gt;появилась в публичной сфере&lt;/a&gt;, то теперь об этом можно говорить открыто.&lt;/p&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjblt88QnNGZN2K2TFpzpigRt1-RgCzQvCBgQ_tMZ0tgaTqkx9J8QPadyOXiThEJQebFm5l8Vs461hQuOhf4i8N8pzGF-JE4FwJqtYEYS_NArYXFcyJ4Lh20VGlxOdnQ_P3Horx2FzNscDLRFjsWuDq_YgW0CTgFyb6BeCGkNjM1YGAegwwu_83arha_hg/s3019/Screenshot-20251225_0852.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;600&quot; data-original-height=&quot;1692&quot; data-original-width=&quot;3019&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjblt88QnNGZN2K2TFpzpigRt1-RgCzQvCBgQ_tMZ0tgaTqkx9J8QPadyOXiThEJQebFm5l8Vs461hQuOhf4i8N8pzGF-JE4FwJqtYEYS_NArYXFcyJ4Lh20VGlxOdnQ_P3Horx2FzNscDLRFjsWuDq_YgW0CTgFyb6BeCGkNjM1YGAegwwu_83arha_hg/s600/Screenshot-20251225_0852.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Подробностей у меня самого нет, т.к. все это происходило без моего участия. Люди просто взяли SObjectizer и сделали на нем то, что им было нужно. Может быть, если повезет, кто-то из участников проекта решится написать на Хабре или где-то еще о своих впечатлениях. Было бы здорово. В том числе и в плане PR-а для нашего открытого проекта.&lt;/p&gt;

&lt;p&gt;Ну а пока это все, что получается рассказать.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/5438273199154064215/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/5438273199154064215' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/5438273199154064215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/5438273199154064215'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2025/12/progc-yadro-sobjectizer.html' title='[prog.c++] Компания YADRO использует SObjectizer в одном из своих проектов'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjblt88QnNGZN2K2TFpzpigRt1-RgCzQvCBgQ_tMZ0tgaTqkx9J8QPadyOXiThEJQebFm5l8Vs461hQuOhf4i8N8pzGF-JE4FwJqtYEYS_NArYXFcyJ4Lh20VGlxOdnQ_P3Horx2FzNscDLRFjsWuDq_YgW0CTgFyb6BeCGkNjM1YGAegwwu_83arha_hg/s72-c/Screenshot-20251225_0852.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-8686742677635637037</id><published>2025-12-24T16:50:00.003+03:00</published><updated>2025-12-24T16:50:45.269+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Павбывавбы"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[c++.flame] Желтушные заголовки: Microsoft собирается переписать весь Сишный и C++ный код на Rust!</title><content type='html'>&lt;p&gt;...или очередная история о том, как &lt;a href=&quot;https://pikabu.ru/story/uchyonyiy_iznasiloval_zhurnalista_ili_yevolyutsiya_nauchnoy_novosti_4294500&quot;&gt;ученый изнасиловал журналиста&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Настоящая шок-сенсация &lt;a href=&quot;https://habr.com/ru/news/979612/&quot;&gt;в статье на Хабре&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
Microsoft планирует модернизировать свои крупнейшие кодовые базы и к концу десятилетия полностью исключить весь код на C/C++, заменив его на Rust.
&lt;/blockquote&gt;

&lt;p&gt;Со ссылкой &lt;a href=&quot;https://www.thurrott.com/dev/330980/microsoft-to-replace-all-c-c-code-with-rust-by-2030&quot;&gt;на источник на английском языке&lt;/a&gt;, который говорит о том же:&lt;/p&gt;

&lt;blockquote&gt;
Microsoft is taking an impressive step in modernizing its biggest codebases and will eliminate all C/C++ code by the end of the decade, replacing it with Rust.
&lt;/blockquote&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhloXLkMzeTjqLjzqpXhoM8vj0tAP6h9ojpQoJvhLzubzASoip8QeeDVudeD3GjrEgbMd4F_GCGHo6MUSh0xB7FMs9xkpg6LG1yTcYzmaBI1QF694I1Z2KdvESZfTi52jJams6JvqaG0hHnlQxynLePjseGyrcIheAbxRDaN1hiouBfXMGs_oRO6_v6VWQ/s2067/Screenshot-20251224-1644.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;600&quot; data-original-height=&quot;1565&quot; data-original-width=&quot;2067&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhloXLkMzeTjqLjzqpXhoM8vj0tAP6h9ojpQoJvhLzubzASoip8QeeDVudeD3GjrEgbMd4F_GCGHo6MUSh0xB7FMs9xkpg6LG1yTcYzmaBI1QF694I1Z2KdvESZfTi52jJams6JvqaG0hHnlQxynLePjseGyrcIheAbxRDaN1hiouBfXMGs_oRO6_v6VWQ/s600/Screenshot-20251224-1644.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Для старых &lt;strike&gt;упоротых&lt;/strike&gt; C++ников, вроде меня, новость из категории &quot;А-А-А, мама, мы все умрем! Вот прям завтра помрем вааапще все!!!&quot;&lt;/p&gt;

&lt;p&gt;Признаться, я сам купился на заголовки поленившись дойти до первоисточника. А стоило бы...&lt;/p&gt;

&lt;p&gt;На самом деле некий инженер из Microsoft, работающий над экспериментальным проектом, &lt;a href=&quot;https://www.linkedin.com/posts/galenh_principal-software-engineer-coreai-microsoft-activity-7407863239289729024-WTzf/&quot;&gt;запостил у себя в LinkedIn&lt;/a&gt; ссылку на вакансию в своей команде. Мол, ищем разработчика под амбициозный проект. И личной целью этого самого инженера является полная замена кода на Си и C++. Личной целью конкретного руководителя какого-то экспериментального проекта внутри Microsoft.&lt;/p&gt;

&lt;p&gt;Между тем разнеслось по нашим Интернетикам это так, будто Microsoft уже принял окончательное и бесповоротное решение по переписыванию имеющихся кодовых баз. И, более того, установил сроки для этого самого переписывания.&lt;/p&gt;

&lt;p&gt;Бзик конкретного человека (я бы сказал, безумная вера в утопическое будущее) разогнали до планетарного масштаба.&lt;/p&gt;

&lt;p&gt;Тьфу, срамота.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/8686742677635637037/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/8686742677635637037' title='Комментарии: 1'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/8686742677635637037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/8686742677635637037'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2025/12/cflame-microsoft-c-rust.html' title='[c++.flame] Желтушные заголовки: Microsoft собирается переписать весь Сишный и C++ный код на Rust!'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhloXLkMzeTjqLjzqpXhoM8vj0tAP6h9ojpQoJvhLzubzASoip8QeeDVudeD3GjrEgbMd4F_GCGHo6MUSh0xB7FMs9xkpg6LG1yTcYzmaBI1QF694I1Z2KdvESZfTi52jJams6JvqaG0hHnlQxynLePjseGyrcIheAbxRDaN1hiouBfXMGs_oRO6_v6VWQ/s72-c/Screenshot-20251224-1644.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-6675204131695839065</id><published>2025-12-02T16:15:00.000+03:00</published><updated>2025-12-02T16:15:05.623+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Вопрос залу"/><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Интересно, а какой код понятнее?</title><content type='html'>&lt;p&gt;В современном C++ одни и те же вещи можно сделать по разному.&lt;/p&gt;

&lt;p&gt;Например, у нас есть список типов, для каждого из которых нужно сделать какое-то действие. Что-то вроде for_each-а, но для списка типов.&lt;/p&gt;

&lt;p&gt;Можно сделать это вот так:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;... Types&amp;gt;&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;void&lt;/font&gt;&amp;nbsp;for_each_type_via_lambda(&lt;font color=&quot;#90f020&quot;&gt;int&lt;/font&gt;&amp;nbsp;arg) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;const&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#90f020&quot;&gt;auto&lt;/font&gt;&amp;nbsp;action = [arg]&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;T&amp;gt;() {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;typeid&lt;/font&gt;(T).name() &amp;lt;&amp;lt;&amp;nbsp;&lt;font color=&quot;#ffa0a0&quot;&gt;&amp;quot; - &amp;quot;&lt;/font&gt;&amp;nbsp;&amp;lt;&amp;lt; arg &amp;lt;&amp;lt; std::endl;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(action.&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;operator&lt;/font&gt;()&amp;lt;Types&amp;gt;(), ...);&lt;br&gt;
}&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Здесь используется шаблон лямбда функции, для использования которого нам приходится явно указывать как его вызывать.&lt;/p&gt;

&lt;p&gt;А можно сделать более старым способом, без лямбды, но с помощью вспомогательной функции:&lt;/p&gt;

&lt;table width=&quot;100%&quot; bgcolor=&quot;#000040&quot;&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;font color=&quot;#c0c0c0&quot;&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;&amp;nbsp;T&amp;gt;&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;void&lt;/font&gt;&amp;nbsp;do_something(&lt;font color=&quot;#90f020&quot;&gt;int&lt;/font&gt;&amp;nbsp;arg) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::cout &amp;lt;&amp;lt;&amp;nbsp;&lt;font color=&quot;#ffff60&quot;&gt;typeid&lt;/font&gt;(T).name() &amp;lt;&amp;lt;&amp;nbsp;&lt;font color=&quot;#ffa0a0&quot;&gt;&amp;quot; - &amp;quot;&lt;/font&gt;&amp;nbsp;&amp;lt;&amp;lt; arg &amp;lt;&amp;lt; std::endl;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;template&lt;/font&gt;&amp;lt;&lt;font color=&quot;#90f020&quot;&gt;typename&lt;/font&gt;... Types&amp;gt;&lt;br&gt;
&lt;font color=&quot;#90f020&quot;&gt;void&lt;/font&gt;&amp;nbsp;for_each_type(&lt;font color=&quot;#90f020&quot;&gt;int&lt;/font&gt;&amp;nbsp;arg) {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(do_something&amp;lt;Types&amp;gt;(arg), ...);&lt;br&gt;
}&lt;br&gt;
      &lt;/font&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;Результат будет один и тот же. Но вот понятность двух этих вариантов лично для меня совершенно разная.&lt;/p&gt;

&lt;p&gt;Интересно, а какой из вариантов более понятен для вас?&lt;/p&gt;

&lt;p&gt;PS. Этот пример &lt;a href=&quot;https://wandbox.org/permlink/G9exF6yadhPd1idA&quot;&gt;на wandbox&lt;/a&gt; &quot;для поиграться&quot;.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/6675204131695839065/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/6675204131695839065' title='Комментарии: 8'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/6675204131695839065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/6675204131695839065'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2025/12/progc.html' title='[prog.c++] Интересно, а какой код понятнее?'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-580370486130390403</id><published>2025-12-01T19:21:00.000+03:00</published><updated>2025-12-01T19:21:07.377+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Кино"/><category scheme="http://www.blogger.com/atom/ns#" term="О жизни"/><category scheme="http://www.blogger.com/atom/ns#" term="Ссылки"/><title type='text'>[life.cinema] Очередной кинообзор (2025/11)</title><content type='html'>&lt;p&gt;Традиционный отчет о просмотренных фильмах. Традиционно в начале каждого из списков то, что понравилось больше, а в конце то, на что можно не тратить свое время. Впрочем, в этот раз из просмотренных сериалов не понравилось вообще ничего, так что там весь список можно смело обойти стороной.&lt;/p&gt;

&lt;p&gt;Фильмы&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/5463792/&quot;&gt;Хищник: Планета смерти (Predator: Badlands, 2025)&lt;/a&gt;. Посмотрел с удовольствием, мне понравилось. Наверное, это лучшее, что сняли после второй части &quot;Хищника&quot;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/5006875/&quot;&gt;Кто она? (The Artifice Girl, 2022)&lt;/a&gt;. Мне понравилось. Но не-айтишникам следить за происходящим на экране может быть сложновато.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/4947321/&quot;&gt;Операция &quot;Наполеон&quot; (Napóleonsskjölin, 2023)&lt;/a&gt;. Это что-то вроде современного Индианы Джонса на минималках, бюджет там явно был мизерный. Но по итогу на удивление неплохо и вполне себе смотрибельно.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/6163953/&quot;&gt;Геля (2025)&lt;/a&gt;. Вполне смотрибельно. Не всё понял по сюжету, но фильм смешной.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/464475/&quot;&gt;Франкенштейн (Frankenstein, 2025)&lt;/a&gt;. Отлично снятая сказка. Если такой жанр нравится, то смело можно смотреть.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/9792159/&quot;&gt;Призрак на поле боя (Un fantasma en la batalla, 2025)&lt;/a&gt;. По сюжету очень перекликается с испанским же &lt;a href=&quot;https://www.kinopoisk.ru/film/7038343/&quot;&gt;Агент под прикрытием&lt;/a&gt;. Но &quot;Призрак...&quot; чуть более суровый и мрачный, как мне показалось. Не шедевр, но смотреть можно.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/4469658/&quot;&gt;Святая ночь. Охотники на демонов (Georukhan bam: demon heonteoseu, 2025)&lt;/a&gt;. Простенько, бюджетненько, но вполне себе смотрибельно. Однако, этот фильм, скорее всего, для очень узкой аудитории: для тех кому нравится корейское кино и, одновременно, кино про демонов и экзорцизм.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/5495672/&quot;&gt;Разрушитель миров (Worldbreaker, 2025)&lt;/a&gt;. В принципе, не самое плохое фэнтези для подростков. Но мне совершенно не хватило экшОна, а без экшОна повествование получилось пресным и затянутым.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/4887748/&quot;&gt;Туман (2023)&lt;/a&gt;. Снято красиво, да. Но это единственное, что есть хорошего в фильме. Сама рассказанная история выглядит каким-то бредом.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/film/8738871/&quot;&gt;Укрытие номер один (Safe House, 2025)&lt;/a&gt;. Очень бюджетно и очень тупо. Лучше пройти мимо этого фильма.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Сериалы&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/5895344/&quot;&gt;Константинополь (первый сезон, 2025)&lt;/a&gt;. Разочарован. Ждал чего-то вроде современной версии фильма &quot;Бег&quot;, но увидел что-то невнятное про борьбу вымышленных ОПГ в вымышленном псевдоисторическом антураже. Жаль потраченного времени.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/4867443/&quot;&gt;Лихие (оба сезона, 2024-2025)&lt;/a&gt;. Развязка просто говно говна. Поэтому не рекомендую тратить на это кино свое время.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://www.kinopoisk.ru/series/6285965/&quot;&gt;Ночной экспресс (Nightsleeper, первый сезон, 2024)&lt;/a&gt;. Купился на высокий рейтинг на Кинопоиске. Редкий маразм. Жаль потраченного времени.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/580370486130390403/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/580370486130390403' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/580370486130390403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/580370486130390403'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2025/12/lifecinema-202511.html' title='[life.cinema] Очередной кинообзор (2025/11)'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-9051753102357440619</id><published>2025-11-28T09:00:00.000+03:00</published><updated>2025-11-28T09:00:22.390+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] История с потреблением памяти из-за фрагментации хипа в mimalloc-е</title><content type='html'>&lt;p&gt;Жила-была одна программа, которая при старте загружала кучу данных, делала некоторую первичную обработку этих данных, а затем переходила в режим ожидания запросов от пользователей. Особенностью первичной обработки было то, что на это время под всякие промежуточные объекты выделялся значительный объем динамической памяти. И после завершения обработки практически вся память должна была быть освобождена.&lt;/p&gt;

&lt;p&gt;Что, собственно, до некоторых пор и происходило: по показаниям htop было видно, как сперва потребление памяти растет, затем резко падает.&lt;/p&gt;

&lt;p&gt;Но в какой-то момент поведение изменилось: потребление памяти росло во время первичной обработки, потом уменьшалось, но уменьшалось не настолько, насколько ожидалось. Грубо говоря, раньше в пике съедали 1Gb, затем падали до 400Mb. Теперь же в пике съедаем 1Gb, но затем падаем всего до 600Mb.&lt;/p&gt;

&lt;p&gt;Естественно, возникло ощущение, что где-то есть утечка. Но никакой утечки не нашли. Зато нашли явные следы фрагментации хипа.&lt;/p&gt;

&lt;blockquote&gt;
&lt;i&gt;Сразу извинения: я не уверен на 100%, что термин &quot;фрагментация&quot; здесь является точным. Но лучшего, увы, не придумал. Поэтому прошу гнилыми помидорами не бросаться.&lt;/i&gt;
&lt;/blockquote&gt;

&lt;p&gt;В проекте в качестве дефолтного аллокатора используется &lt;a href=&quot;https://github.com/microsoft/mimalloc&quot;&gt;mimalloc&lt;/a&gt;. Хвала его создателям, в API mimalloc-а есть средства для интроспекции содержимого хипа, что и позволило обнаружить эффект фрагментации.&lt;/p&gt;

&lt;p&gt;Нужно сказать, что mimalloc спроектирован так, чтобы максимально избавиться от вероятности фрагментации (насколько это в принципе возможно для языков без compacting GC): он использует арены (areas) под объекты фиксированного размера. Так, объекты размером в 16 байт создаются в своей арене, объекты размером в 32 байта -- в своей, размером 48 байт -- в своей и т.д. Тем самым mimalloc частично избавляется от эффекта &quot;дырок в сыре&quot; -- когда суммарно свободной памяти много, но вся она рассредоточена в мелких фрагментах, чередующихся с занятыми фрагментами.&lt;/p&gt;

&lt;p&gt;Выяснилось, что под контролем mimalloc-а оказываются буквально сотни арен для объектов размером 16 и 48 байта, на которых живых всего пара-тройка объектов, а все остальное пространство пустое. Но т.к. на этих аренах есть живые объекты, то mimalloc не может отдать выделенную под арены память обратно ОС. Поэтому ОС показывает, что приложение держит больше памяти, чем мы рассчитывали.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Почему же так произошло?&lt;/p&gt;

&lt;p&gt;Первичная обработка данных при старте создает в динамической памяти множество объектов. Среди них огромный процент объектов как раз имеют размер 16 и 48 байт. Под них mimalloc динамически выделяет все новые и новые арены, запрашивая память у ОС.&lt;/p&gt;

&lt;p&gt;При завершении обработки эти вспомогательные объекту удаляются. И ранее их удаление приводило к очистке тех арен mimalloc-а, в которых объекты размещались. По мере освобождения арен mimalloc возвращал память ОС. И по показаниям htop было видно, что потребление памяти приложением снижается.&lt;/p&gt;

&lt;p&gt;Но после того, как кусочек приложения был переведен на использование нового, написанного мной под особенности задачи, контейнера с деревом внутри, возник эффект, при котором в этих самых аренах оставались единицы живых объектов. Поэтому-то арены полностью не освобождались и не возвращались ОС.&lt;/p&gt;

&lt;p&gt;Происходило это потому, что в процессе обработки начали создаваться не только &quot;старые&quot; объекты размером 16 и 48 байт, но и &quot;новые&quot; -- внутри этого самого нового контейнера. Только вот содержимое нового контейнера должно было остаться до конца работы программы, поэтому эти &quot;новые&quot; объекты не удалялись. В отличии от &quot;старых&quot; объектов, нужных только на время первичной обработки.&lt;/p&gt;

&lt;p&gt;Получалось, что сплошным потоком создаются объекты размером, например, 48 байт. Львиная их часть относится к &quot;старым&quot; объектам, но иногда создаются и &quot;новые&quot;. Пропорция приблизительно 500 &quot;старых&quot; объектов к одному &quot;новому&quot;. Т.е. создали 500 &quot;старых&quot; объектов, затем один &quot;новый&quot;, затем еще 500 &quot;старых&quot;, затем еще один &quot;новый&quot; и т.д.&lt;/p&gt;

&lt;p&gt;Физически это выглядит так, что на очередной арене mimalloc-а подряд размещается 500 &quot;старых&quot; объектов, за ними один &quot;новый&quot;, затем еще 500 &quot;старых&quot;, следом еще один &quot;новый&quot;, затем арена заканчивается, начинается новая, на которой сперва идет 500 &quot;старых&quot; объектов, затем один &quot;новый&quot; и т.д.&lt;/p&gt;

&lt;p&gt;В итоге &quot;старые&quot; и &quot;новые&quot; объекты короткое время живут вместе внутри одних и тех же арен mimalloc-а. И когда после завершения первичной обработки &quot;старые&quot; объекты удаляются, то &quot;новые&quot; остаются. Именно они и являются той парой-тройкой все еще живых объектов внутри практически пустых арен.&lt;/p&gt;

&lt;p&gt;В результате вроде как и утечек нет, все объекты корректно удалились. Но и сотни мегабайт неиспользуемой приложением памяти не были возвращены ОС.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;К счастью выяснилось, что в реализации моего нового контейнера есть ошибка -- это самое дерево внутри содержало раз в 10 больше узлов, чем требуется. Тупо ошибся с расчетом размера одного узла дерева, поэтому узлы создавались слишком маленькими, а чтобы компенсировать уменьшившийся размер пришлось создавать больше узлов.&lt;/p&gt;

&lt;p&gt;Отсюда и возникала пропорция одного &quot;нового&quot; объекта (тот самый узел дерева) к пятистам &quot;старым&quot; объектам.&lt;/p&gt;

&lt;p&gt;После исправления найденной ошибки количество узлов резко сократилось и эффект, при котором есть множество практически пустых арен с парой-тройкой живых объектов внутри, исчез. Теперь количество таких арен измеряется буквально единицами.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Для меня главный практический вывод -- это то, насколько языки с GC (особенно с продвинутыми compacting GC) могут облегчить жизнь программиста. Да, там возникают другие проблемы. Но в данном случае compacting GC был бы очень в тему, на мой взгляд.&lt;/p&gt;

&lt;p&gt;Ну а так-то конкретно повезло, что первопричиной была моя глупая ошибка. Было бы гораздо хуже, если бы такой эффект возникал бы при полностью корректной работе.&lt;/p&gt;

&lt;p&gt;Т.е. сценарий, когда одним потоком в хипе аллоцируются коротко- и длинноживущие объекты, потенциально возможен. А значит и возможна ситуация, когда после удаления короткоживущих объектов приложение продолжит потреблять в разы больше памяти, чем нужно.&lt;/p&gt;

&lt;p&gt;Если бы события развивались бы по такому худшему сценарию нам бы пришлось пересматривать политику создания &quot;старых&quot; объектов, которые нужны только на время первичной обработки данных.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/9051753102357440619/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/9051753102357440619' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/9051753102357440619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/9051753102357440619'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2025/11/progc-mimalloc.html' title='[prog.c++] История с потреблением памяти из-за фрагментации хипа в mimalloc-е'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-6324950529366050514</id><published>2025-11-24T07:43:00.000+03:00</published><updated>2025-11-24T07:43:13.344+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="Павбывавбы"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] Не нужно делать собственные специализации std::hash&amp;lt;std::pair&amp;lt;T,U&amp;gt;&amp;gt;</title><content type='html'>&lt;p&gt;Некоторое время назад я сам наткнулся на грабли при использовании библиотеки Folly. Мне потребовался std::hash для std::pair&amp;lt;int, some_my_type&amp;gt;, при этом std::hash для some_my_type у меня уже был. Поэтому я сделал специализацию std::hash для std::pair&amp;lt;int, some_my_type&amp;gt;, в которой использовал std::hash&amp;lt;some_my_type&amp;gt;. Собрал код, стал проверять и выяснил, что на некоторых тестовых сценариях происходит что-то странное. Начал разбираться и внезапно обнаружил, что мой std::hash для std::pair&amp;lt;int, some_my_type&amp;gt; не вызывается вообще.&lt;/p&gt;

&lt;p&gt;Дело оказалось в том, что разработчики Folly подложили свинью своим пользователям и &lt;a href=&quot;https://github.com/facebook/folly/blob/15be0f5667d8543539b5b17c0cadddc4d07f6090/folly/hash/Hash.h#L1290-L1297&quot;&gt;определили специализацию std::hash&amp;lt;std::pair&amp;lt;T, U&amp;gt;&amp;gt;&lt;/a&gt;. Чего делать по стандарту нельзя (за цитату из стандарта большое спасибо Константину Шарону):&lt;/p&gt;

&lt;blockquote&gt;
 • [namespace.std] (C++23 draft, §16.4.2.2/1):&lt;br/&gt;
The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std, unless otherwise specified.&lt;br/&gt;
 • The only allowed exception is that you may specialize certain templates in std for user-defined types.&lt;br/&gt;
&lt;br/&gt;
[unord.hash] (C++23 draft, §24.5.4.2/1):
For all object types Key for which there exists a specialization std::hash&lt;Key&gt;, the program may define additional specializations of std::hash&lt;Key&gt; for user-defined types.
&lt;/blockquote&gt;

&lt;p&gt;Тут особый упор нужно сделать на &quot;for user-defined types&quot;, тогда как std::pair&amp;lt;T, U&amp;gt; -- это не user-defined type. Вот std::pair&amp;lt;int, some_my_type&amp;gt; -- это уже user-defined type и для него специализацию std::hash делать можно.&lt;/p&gt;

&lt;p&gt;Об этом несколько месяцев назад я &lt;a href=&quot;https://www.linkedin.com/posts/eao197_%D0%B5%D1%81%D0%BB%D0%B8-%D0%BC%D0%BD%D0%B5-%D0%BD%D0%B5-%D0%B8%D0%B7%D0%BC%D0%B5%D0%BD%D1%8F%D0%B5%D1%82-%D1%81%D0%BA%D0%BB%D0%B5%D1%80%D0%BE%D0%B7-%D1%82%D0%BE-%D0%B2-c-%D0%B2-activity-7366747784084910082-2tKy&quot;&gt;писал в LinkedIn&lt;/a&gt;. Но недавно на Reddit-е обнаружил ссылку на статью &lt;a href=&quot;https://cpp-rendering.io/hashing-in-c/&quot;&gt;Simplify hashing in C++&lt;/a&gt; в которой, ни много, ни мало, предлагается делать тоже самое, т.е. определять специализации std::hash для std::pair&amp;lt;T, U&amp;gt;.&lt;/p&gt;

&lt;p&gt;Поскольку такое заблуждение существует, то приходится заострять на этом внимание. Поэтому, пожалуйста, не делайте собственные специализации std::hash&amp;lt;std::pair&amp;lt;T, U&amp;gt;&amp;gt;.&lt;/p&gt;

&lt;p&gt;А если вы сомневаетесь в правильности того, о чем я говорю, то представьте себе ситуацию:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;вы разрабатываете программу и определили какой-то собственный тип your_type;&lt;/li&gt;
  &lt;li&gt;вы захотели использовать your_type в качестве ключа в unordered_map и сделали для your_type специализацию std::hash;&lt;/li&gt;
  &lt;li&gt;затем вы захотели сэкономить себе время и силы и сделали специализацию std::hash для std::pair&amp;lt;T, U&amp;gt;. Теперь у вас автоматически поддерживается хеширование и для std::pair&amp;lt;int, your_type&amp;gt;, и для std::pair&amp;lt;your_type, int&amp;gt;, и прочих сочетаний your_type с другими типами, поддерживающими кэширование;&lt;/li&gt;
  &lt;li&gt;где-то в программе вы используете std::unordered_set&amp;lt;std::pair&amp;lt;int, your_type&amp;gt;&amp;gt;&lt;/li&gt;
  &lt;li&gt;все у вас работает нормально;&lt;/li&gt;
  &lt;li&gt;затем в один прекрасный момент вы подключаете в проект стороннюю библиотеку, в которую отдаете your_type, и которая использует std::pair&amp;lt;int, your_type&amp;gt; в качестве ключа в Folly::F14FastMap;&lt;/li&gt;
  &lt;li&gt;и тут оказывается, что у вас в проекте есть два определения для std::hash&amp;lt;std::pair&amp;lt;int, your_type&amp;gt;&amp;gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Поздравляю, у вас в коде Undefined Behaviour из-за нарушения one definition rule.&lt;/p&gt;

&lt;p&gt;Реально хотите собственными руками подсаживать UB в код?&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Разработчиков Folly понять можно: они делали Folly для своих собственных нужд и в их программах, разработанных под задачи Facebook-а, вряд ли могут встретиться другие специализации для std::hash. А то, что Folly применяют и за пределами Facebook-а, в том числе смешивая в одном проекте Folly с кучей других библиотек -- это не проблемы разработчиков Folly.&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/6324950529366050514/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/6324950529366050514' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/6324950529366050514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/6324950529366050514'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2025/11/progc-stdhash.html' title='[prog.c++] Не нужно делать собственные специализации std::hash&amp;lt;std::pair&amp;lt;T,U&amp;gt;&amp;gt;'/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-654279083390275842.post-116054436421923583</id><published>2025-11-21T13:34:00.002+03:00</published><updated>2025-11-21T13:34:41.759+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SObjectizer"/><category scheme="http://www.blogger.com/atom/ns#" term="О программировании"/><category scheme="http://www.blogger.com/atom/ns#" term="О работе"/><category scheme="http://www.blogger.com/atom/ns#" term="язык C++"/><title type='text'>[prog.c++] SObjectizer-5 пятнадцать лет! </title><content type='html'>&lt;p&gt;Неумолимо быстро летит время и вот уже SObjectizer-5 исполняется пятнадцать лет.&lt;/p&gt;

&lt;p&gt;Очень многое из того, я мог бы сказать по этому поводу уже сказано в 2020-ом году &lt;a href=&quot;https://eao197.blogspot.com/2020/12/progc-sobjectizer-5.html&quot;&gt;здесь&lt;/a&gt;. Если кто-то еще не читал тот пост, приуроченный к 10-летней годовщине, то настоятельно рекомендую сделать это, ибо все нижеследующее будет лишь дополнение к тому лонгриду.&lt;/p&gt;

&lt;p&gt;Но прежде чем перейти к подробностям, слова искренней благодарности всем, кто тем или иным способом поддерживал наш проект. Вряд ли бы мы справились, если бы не ваш интерес и внимание. Спасибо от всей души!&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Работа над SObjectizer в последние пять лет шла урывками.&lt;/p&gt;

&lt;p&gt;В очередной раз повторюсь: непосредственно SObjectizer денег нам не приносит. Разве что создает некую репутацию и, как и RESTinio, приводит клиентов, которые увидев наши разработки предлагают нам тем или иным образом поучаствовать в решении их задач.&lt;/p&gt;

&lt;p&gt;Т.е. зарабатывать на жизнь приходится не развивая SObjectizer за деньги внешних спонсоров, а трудясь на чужих проектах, зачастую никак с SObjectizer-ом (или RESTinio) не связанных. Что отнимает значительную часть времени и сил. А уже на том, что остается, делаются очередные версии SObjectizer-а.&lt;/p&gt;

&lt;p&gt;Такова была ситуация в последние годы. Таковой она, судя по всему, и останется в будущем.&lt;/p&gt;

&lt;p&gt;Поэтому бурного развития SObjectizer-а можно не ждать. Мы неторопливо и спокойно спускаемся с горы (если вы понимаете о чем я 😉)&lt;/p&gt;

&lt;p&gt;Тем более что...&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;...SObjectizer уже давно вобрал в себя то, что было нужно именно нам. И если бы SObjectizer использовали только мы, то у SObjectizer-а случилось бы два-три корректирующих релиза, вряд ли больше.&lt;/p&gt;

&lt;p&gt;То, что сейчас добавляется в SObjectizer, добавляется только потому, что это где-то кому-то потребовалось и этот кто-то нашел время и желание нам сообщить о своих хотелках.&lt;/p&gt;

&lt;p&gt;При этом внутренняя сложность SObjectizer растет и эту сложность желательно держать под контролем. А один из самых действенных способов контроля -- это отказ от желания затащить в SO-5 все, что только возможно.&lt;/p&gt;

&lt;p&gt;Поэтому период &quot;добавляем фичу просто для того, чтобы была&quot; закончился давным давно. Добавить что-то нужное и полезное -- это да, это мы с удовольствием. Но если никто ничего не просит, то значит имеющегося достаточно 😉&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Одна из вещей, которой мы уделяли особое влияние, была совместимость между версиями SO-5. В течении почти пяти лет мы старались не ломать совместимость в рамках ветки 5.5. В середине 2019-го появилась ветка 5.6, в которой пришлось &lt;a href=&quot;https://habr.com/ru/articles/453256/&quot;&gt;резать по живому&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;А за 5.6 последовали ветки 5.7 (январь 2020-го) и 5.8 (июнь 2023-го). Но их я сам рассматриваю как последовательное развитие ветки 5.6. К сожалению, без ломающих изменений не обошлось. Однако, они не настолько кардинальные, как это было при переходе от 5.5 к 5.6. В основном изменения между 5.7 и 5.8 в касались очень специфических внутренних интерфейсов SObjectizer-а и в гораздо меньшей степени затрагивали обычный пользовательский код.&lt;/p&gt;

&lt;p&gt;В этом же ключе собираемся двигаться и дальше. Ибо чем старше становлюсь, тем больше ценю возможность взять древний код и без лишних телодвижений заставить работать его с новыми версиями библиотек. Не могу гарантировать, что ветка 5.8 будет развиваться еще в течении 5 или 10 лет (хотя меня бы лично это очень бы порадовало), но мы будем к этому стремиться.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Есть одна важная фраза, написанная пять лет назад:&lt;/p&gt;

&lt;blockquote&gt;
В общем, SObjectizer-5 поступательно развивается уже 10 лет, что лично меня приятно удивляет. Ведь запаса SObjectizer-4 хватило всего-то на 3-4 года. Тогда как SObjectizer-5 может эволюционировать еще несколько лет и насущной необходимости делать условный SObjectizer-6 на новых идеях пока не видно.
&lt;/blockquote&gt;

&lt;p&gt;Можно констатировать, что время подтвердило эти слова: SObjectizer-5 все еще развивается и насущной необходимости делать условный SObjectizer-6 на новых идеях пока что не видно.&lt;/p&gt;

&lt;p&gt;Это значит, что из опыта SObjectizer-4 были сделаны более чем правильные выводы.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Теперь же несколько слов об очень приятном факторе, который для меня до сих пор выглядит фантастическим.&lt;/p&gt;

&lt;p&gt;В 2021-ом году SObjectizer-ом заинтересовался &lt;a href=&quot;https://www.linkedin.com/in/marcoarena/&quot;&gt;Марко Арена&lt;/a&gt;, лидер сообщества 
&lt;a href=&quot;https://www.italiancpp.org/&quot;&gt;Italian C++ Community&lt;/a&gt;. И со временем он внес очень существенный вклад как в популяризацию SObjectizer-а, так и в его развитие. Так, сперва мой коллега, Коля Гродзицкий, &lt;a href=&quot;https://eao197.blogspot.com/2021/03/progc-sobjectizer-italian-c-community.html&quot;&gt;сделал доклад&lt;/a&gt; о SObjectizer-е на виртуальном митапе. Затем Марко &lt;a href=&quot;https://eao197.blogspot.com/2024/04/progworkwow-sobjectizer.html&quot;&gt;опубликовал замечательную серию статей о SObjectizer-е&lt;/a&gt;. А недавно Марко еще и выступил с &lt;a href=&quot;https://x.com/xpugbologna/status/1975975260437860746?s=20&quot;&gt;собственным докладом о SObjectizer-е&lt;/a&gt;. Это первый из известных мне докладов о SO-5, который был сделан кем-то не из команды разработки SObjectizer-а.&lt;/p&gt;

&lt;p&gt;Но кроме серьезной работы по продвижению SObjectizer-а &quot;в массы&quot; Марко задал множество хороших вопросов и высказал ряд интересных соображений, на основании которых затем в SObjectizer были добавлены новые фичи.&lt;/p&gt;

&lt;p&gt;И это тот самый элемент везения, которого нам так не хватало и за который остается только поблагодарить судьбу. Марко, если ты вдруг читаешь этот пост, то огромное тебе спасибо! Смело могу сказать, что если бы не твое участие, SObjectizer не был бы сейчас так развит.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Ну и самый важный лично для меня аспект, а именно ответ на вопрос &quot;почему я все еще занимаюсь SObjectizer-ом?&quot;&lt;/p&gt;

&lt;p&gt;Пять лет назад я уже дал исчерпывающий ответ на этот вопрос. Но этот ответ был актуален на 2020-й год: главной (но не единственной) причиной было желание сделать из SObjectizer-а полноценный продукт за который не стыдно.&lt;/p&gt;

&lt;p&gt;Это было сделано. За SObjectizer-5 уже давно не стыдно. И за прошедшее время, надеюсь, наша разработка стала только лучше.&lt;/p&gt;

&lt;p&gt;Но если эта цель была достигнута, то что движет мной теперь?&lt;/p&gt;

&lt;p&gt;Вероятно, действуют вот эти причины:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;просто потому, что могу;&lt;/li&gt;
  &lt;li&gt;потому, что это &quot;мое&quot;, в самом широком смысле этого слова. Начиная от идей, заканчивая полной ответственностью при полной свободе в принятии собственных решений. Это то ощущение, которое никогда не получишь работая исполнителем на чужом проекте;&lt;/li&gt;
  &lt;li&gt;привычка. Это часть моей жизни в течении очень и очень долгого времени. Не самая плохая часть. И если у меня есть возможность продлить ее, то почему бы и нет?&lt;/li&gt;
&lt;/ul&gt;

&lt;hr/&gt;

&lt;p&gt;Если кому-то интересны ответы на вопросы о том, что ждет проект дальше и насколько рискованно брать его в работу, то могу лишь сослаться на то, что писал пять лет назад:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://eao197.blogspot.com/2020/12/progc-sobjectizer-5.html#current_state_and_future&quot;&gt;Состояние SObjectizer-а и его перспективы&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://eao197.blogspot.com/2020/12/progc-sobjectizer-5.html#is_it_safe_to_choose_it&quot;&gt;Брать или не брать такой SObjectizer в работу?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Там все уже было сказано. Сказать лучше не получится. Надеюсь только, что сам факт развития SObjectizer-5 в течении 15 лет что-то да говорит.&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Чем сейчас можно помочь SObjectizer-у?&lt;/p&gt;

&lt;p&gt;На мой взгляд, сейчас, как и 5 лет назад, SObjectizer больше всего нуждается в двух вещах:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;распространении информации о нем. Если вы попробовали SObjectizer и он вам понравился или не понравился, то найдите, пожалуйста, время и возможность поделиться этим в Интернете. Поверьте, даже коротенький пост из одного предложения в Twitter-е оказывается огромным подспорьем в нашей работе;&lt;/li&gt;
  &lt;li&gt;обратной связи: если вам что-то не понравилось в SObjectizer или чего-то не хватает, сообщите, пожалуйста, нам об этом. Мы не сможем добавить в SObjectizer то, о чем не знаем.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr/&gt;

&lt;p&gt;Ну а теперь перечень фич и изменений, которыми оброс SObjectizer за прошедшие пять лет. В качестве краткого отчета о проделанной работе, так сказать 😀&lt;/p&gt;

&lt;p&gt;Добавлена возможность брать под контроль создание рабочих нитей в штатных диспетчерах SObjectizer-а: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.7.3#a-possibility-to-provide-own-threads-to-sobjectizers-dispatchers-is-introduced&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;В класс agent_t добавлен метод so_deactivate_agent: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.7.3#new-method-so_deactivate_agent-added-to-agent_t-class&quot;&gt;тыц&lt;/a&gt;.
Затем в довесок был добавлен метод so_drop_all_subscriptions_and_filters: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.8.5#a-new-method-so_drop_all_subscriptions_and_filters-for-agents&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Для агента теперь можно назначить собственный MPSC-mbox в качестве direct-mbox-а: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.7.4#its-possible-to-set-a-custom-mpsc-mbox-as-the-direct-mbox-for-an-agent&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Теперь delivery filters можно устанавливать даже на MPSC-mbox-ы: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.7.4#delivery-filters-can-now-be-used-with-mpsc-mboxes&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Серьезно изменился интерфейс abstract_message_box_t. Добавилось понятие delivery_mode для того, чтобы можно было понять из какого контекста сообщения отсылаются (например, если сообщение идет с нити таймера, то в этом случае нельзя блокировать отправителя сообщения). При этом теперь mbox-ам не нужно заниматься контролем message limits. &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.8.0#the-so_5abstract_message_box_t-interface-has-been-changed&quot;&gt;Тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Добавлено понятие message_sink-а. Теперь в качестве подписчика для mbox-а может выступать не только агент, но и вообще произвольна сущность, реализующая интерфейс abstract_message_sink: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/SO-5.8-InDepth-Message-Sinks&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Добавлена возможность регистрировать в SOEnv именованные mbox-ы, которые были созданы пользователем, а не SObjectizer-ом: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.8.0#new-method-so_5environment_tintroduce_named_mbox-has-been-added&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Сделаны шаги в сторону лучшего обеспечения noexcept-гарантий со стороны SObjectizer-а при выполнении дерегистрации кооперации: изменен интерфейс event_queue_t, добавлены диспетчеры nef_one_thread, nef_thread_pool: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.8.0#several-steps-towards-noexcept-ness-of-coop-deregistration-procedure&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;В класс agent_t добавлены методы so_5::agent_t::so_this_agent_disp_binder() и so_5::agent_t::so_this_coop_disp_binder() чтобы можно было узнать, с какими диспетчерами агент связан: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.8.1#new-methods-so_5agent_tso_this_agent_disp_binder-and-so_5agent_tso_this_coop_disp_binder&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Появилась поддержка имен для агентов: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/SO-5.8-InDepth-Optional-Agent-Name&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Расширен набор инструментов для юнит-тестирования агентов: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.8.4#more-advanced-version-of-so_5experimentaltestingreceives&quot;&gt;тыц&lt;/a&gt; и &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.8.4#new-helper-methods-for-expecting-results-in-testing-scenarios&quot;&gt;тыц&lt;/a&gt;, и &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.8.3#new-features-for-testing-of-agents&quot;&gt;тыц&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Добавлена возможность выбросить все ждущие своей очереди заявки для агента при начале дерегистрации агента: &lt;a href=&quot;https://github.com/Stiffstream/sobjectizer/wiki/v.5.8.5#a-new-agent-tuning-option-skip_demands_on_dereg&quot;&gt;тыц&lt;/a&gt;&lt;/p&gt;

&lt;hr/&gt;

&lt;p&gt;Как-то все это получилось сухо и официально. Если жизнь предоставит возможность написать такой же пост в 2030-ом году, то постараюсь сделать аналогичный пост, посвященный 20-летию, более живым и эмоциональным 😉&lt;/p&gt;

</content><link rel='replies' type='application/atom+xml' href='http://eao197.blogspot.com/feeds/116054436421923583/comments/default' title='Комментарии к сообщению'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/654279083390275842/116054436421923583' title='Комментарии: 0'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/116054436421923583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/654279083390275842/posts/default/116054436421923583'/><link rel='alternate' type='text/html' href='http://eao197.blogspot.com/2025/11/progc-sobjectizer-5.html' title='[prog.c++] SObjectizer-5 пятнадцать лет! '/><author><name>eao197</name><uri>http://www.blogger.com/profile/17283739752119445290</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>