Ох уж этот СиПлюсПлас

Так получилось что я научился писать на языке С++. Как так получилось? Амбиции, тщеславие, желание вые***ться. Главные чувства, пульсирующие в моём сердце, когда я слушал лекцию Рылова В. по плюсам в нгу на фите. До сих пор помню его слова:

" Спустя два года изучения, я понял что знаю весь язык в совершенстве. Спустя семь лет практики я осознал, что не знаю его совсем. "

(с) Рылов В.

Я начал кодить на плюсах примерно на втором курсе универа, т.е. 2015 год. Сейчас двадцать четвертый, жесть. Девять лет прошло. Конечно я не кодил непрерывно на этом языке. Последний год до работы на заводе я вообще бросил их, обещая себе наивно, что не вернусь к ним. Думал, что перешёл на Python. Но... Вот я снова с ними. В первые года отношений я испытывал влюблённость, меня тянуло к ним как сейчас тянет к своей мадам. Но потом стали появляться звоночки. Причём громкие. Мне больно было слушать их. Сердце разрывалось. Я не понимал, язык ведь идеальный, на нём можно столько крутого всего делать. На нём делают ААА игры (и ни на чём больше!), потому что такой уровень науки (да-да, в компьютерных играх используются бешенные технологии) можно захерачить только там. Чтобы игра выглядела красиво, игралась драйвово, ничего не лагало. На этом языке такие мощные штуки делаются, ну разве кроме запуска ракет. Там вроде до сих пор Fortran в моде. Короч писец. Язык крутой. И понятное дело не простой. На нём сложно (тогда мне казалось, что это сложно, хи-хи-хи) программировать. Я принял эти правила. Но почему было так больно. Когда...

Я уже не вспомню, что конкретно мне отдавало болью. Поэтому поделюсь сегодняшней задачкой. Я на неё потратил полдня. Имеется вот такой код:

unsigned char i = 10; std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)i;

Вывод:

0a

Код выводит число в шестнадцатеричном формате. Мне, как embedded программисту часто приходится работать именно с этим представлением. Выяснил, что плюсах до 20 стандарта вообще какие-то проблемы с выводом шестнадцатеричных чисел. Есть функции на Си, но блинский, плюсы, ё-моё, а своё?

Идём дальше. Теперь нам потребовалось написать вот так:

unsigned char a = 21; short int b = 69; long long int c = 228; std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)a; std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)b; std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)c;

Вывод:

15 45 e4

Да, кто внимательный, заметил, что пиздец чёт дохуя одинаковой хуйни. Программист на то и программист, что любит избавляться от дублирования. Я по крайней мере точно, у меня это синдром. Прям не могу спокойно на это смотреть. Я специально использовал переменные разного типа данных, чтобы не было соблазна запихать их в массив и в цикле перебрать это добро. Поэтому решение с моей колокольни лишь одно: нужно реализовать собственный манипулятор ввода/вывода, по примеру с setw, setfill или hex. Как истинный гуру программирования я заглянул в свою душу, чтобы отыскать ответ, а душа мне говорит:

Гугли.

Ну а хули, я загуглил. Вот ответ. Портянка слабо говоря немаленькая (именно длину кода я имею в виду). Однако у меня получилось встроить её в проект:

namespace Utils { // переименовал имя класса, структуры и функции struct HexProxy { explicit HexProxy(std::ostream & os) : os(os) {} template <typename Rhs> friend std::ostream & operator<<(HexProxy const& q, Rhs const& rhs) { // эту строчку я видоизменил return q.os << std::setw(2) << std::setfill('0') << std::hex << (int)rhs; } // тут удалил лишние методы private: std::ostream & os; }; // остальное без изменений struct HexCreator {} hex; HexProxy operator<<(std::ostream & os, HexCreator) { return HexProxy(os); } } int main() { unsigned char a = 10; short int b = 10; long long int c = 10; // вот тут магия проявляется std::cout << Utils::hex << a << std::endl; std::cout << Utils::hex << b << std::endl; std::cout << Utils::hex << c << std::endl; }

Итого, что мы имеем. Я добился уменьшения длины строки. Теперь вместо

<< std::setw(2) << std::setfill('0') << std::hex << (int)a

я напишу:

<< Utils::hex << a

Результат на лицо. Я доволен. Пока не начал считать строки кода...

Было 6 строк кода, а теперь 32! Вау, сэкономил ... длину строки. Да, конечно я могу вынести пространство Utils в отдельный файл и подгружать, когда мне нужно воспользоваться этим "волшебным" манипулятором ввода/вывода. НО: а я воспользуюсь им вообще когда-нибудь? Зачем я потратил 4 рабочих часа на это? Ну были бы у меня те 3 длинные строчки (в рабочем проекте мне нужно вывести 6 переменных, но написать пришлось бы всего один разок). Что я получил? На самом деле я получил удовлетворение. Малюсенькое. Да, теперь я спокоен. Но проблема в том, что я это не контролирую. Если я вижу, что могу что-то улучшить, я это делаю практически не задумываясь, чего мне это будет стоить. Сколько сил уйдёт.

Да, вы можете сказать, что не в языке дело, а во мне. Да, это правда. НО блять сука но. Но заключается в том, что этот язык, язык С++ даёт мне кучу возможностей для улучшения. Буквально бесконечную возможность способов себя заебать.

Не так: "я могу вот так сделать круто, а могу вот так круто сделать". Нет. Я могу попробовать 10 способов, которые в результате не дадут никакого эффекта. И только сука 11 способ приведёт меня туда, куда нужно, удовлетворив мой тщеславный перфекционизм. Язык как будто поощряет меня ебать себя через колено. И я как наркоман этим пользуюсь.

В целом вот весь тэйк, я нарик и снова попал в заложники.

22
23 комментария

Ещё один начал изучать плюсы и спятил, отлично

6
Ответить

один единственный вопрос. со знаем с++ ты же теперь наносек же?

2
Ответить

что вы имеете в виду?)

Ответить

Завязывай иначе закончишь как все плюсисты - в рехабе

1
1
Ответить

Лично я закончил с питоном в заднем проходе😎

Ответить

Выяснил, что плюсах до 20 стандарта вообще какие-то проблемы с выводом шестнадцатеричных чисел.С выводом нет, а вот с форматированием строк в целом - похоже, что да. Но можно было использовать буст, там есть похожая функция.
пиздец чёт дохуя одинаковой хуйниМожет, я не вижу подтекста статьи, но почему не выводить повторяющийся код в отдельную функцию? По трудоёмкости оптимально будет, чем свой форматтер ваять. Ну, может быть, вот так:
std::ostream& hex(std::ostream& os, int dec)
{
return os Портянка слабо говоря немаленькая
Я не крестовик, но попробовав разные варианты, пришёл к выводу, что проще, чем так, не сделать.
Думал, может, можно сделать функцию на основе хекса с сигнатурой типа std::basic_ios& hex( std::basic_ios& integer ), но просто так не выйдет сделать такое преобразование. Это надо как-то все данные потока получать, потом делать свой уже символьный поток.
Язык как будто поощряет меня ебать себя через колено.Про плюсы слышал больше негативного, чем позитивного, именно в контексте ёбли и стрельбы в ногу. Но кому-то нравится.
да-да, в компьютерных играх используются бешенные технологииЧё-то вспомнил про быстрый обратный корень, для того времени, думаю, была очень крутая оптимизация. Сейчас, конечно, столько технологий и библиотек понаделано, что все эти приколюхи смысла не имеют. Просто пользуешься готовыми вещами, да и всё.

1
Ответить

Не завезли блоки кода в комментарии, похоже. Вот так я предлагал сделать короче https://gist.github.com/ssproink/09a5eba70d6c30b4842a36fbd5647b7a

1
Ответить