1. C++ / Говнокод #20359

    +4

    1. 1
    2. 2
    auto highPriority = static_cast<bool>(features(w)[5]);
    // Тип features(w) - std::vector<bool>

    Скотт Майерс. Эффективный и современный С++.

    Запостил: Antervis, 10 Июля 2016

    Комментарии (35) RSS

    • Зато слева auto. Эффективно и современно.
      Ответить
      • В С++ нужно вместо устаревшего implicit int вводить современное implicit auto
        Ответить
        • есть уже язык с имплисит ауто

          питон
          Ответить
          • питон++, с блэкджеком и шлюхами!
            auto highPriority = static_cast<auto>(features(w)[5]);
            // Тип features(w) - auto<auto>
            Ответить
        • operator auto();
          Ответить
          • Кстати, template <typename T> operator T(); будет работать?
            Ответить
            • Да.

              Только перегрузка этого оператора - отличный шанс походить по граблям с приоритетами и неоднозначностями...
              Ответить
              • А как же стандарт? Вы в соседнем топике распалялись.
                Ответить
                • А всё по стандарту. Просто если слишком много операторов преобразования и неявных конструкторов понаписать, то потом хер вспомнишь, какой из них должен сработать (а во многих случаях вообще не скомпилится, т.к. варианты будут равнозначными и компилятору придётся выдать об этом ошибку).
                  Ответить
                  • кстати, а у чего приоритет выше - у оператора неявного преобразования или неявного конструктора?
                    Ответить
                    • не ты первый спрашиваешь: google://c++ precedence conversion operator constructor

                      народ пишет что ambiguous/зависит от конпелятора/зависит от констности/зависит от типов и от хез какой еще лабуды. вообщем: как обычно, в крестах.

                      http://stackoverflow.com/questions/1384007/conversion-constructor-vs-conversion-operator-precedence

                      http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-direct-initializati/
                      Ответить
              • > отличный шанс походить по граблям

                Национальный спорт крестовиков.
                Ответить
                • Спортивная ходьба по граблям?
                  Ответить
                  • мне всегда казалось что это крикет: никто не знает и не понимает правил, но самое главное это не опоздать на чайную паузу.

                    жаба это однозначно футбол (25 мужиков долго бегают за одним мячом, "но с ооочень глууубокой стратегией", результат 1:0, и все в восторге!)

                    перл это регби/американский футбол - there can never be enough brute force.

                    питон это бейсбол: бегание по кругу + long shot.
                    Ответить
            • Да. Но всё равно придется специализировать, навешивать const/rvalue-only/lvalue-only перегрузки, а также удалять некоторые некорректные случаи.
              Поэтому проще задать список имплисит преобразований вручную. А еще лучше пользоваться этой фичей только для врапперов и делать максимум одну-две версии перегрузки (const/non-const)
              Ответить
    • Вырвать из контекста, и запостить то, что было "плохим" примером это пять.
      scott meyers effective modern c++. item 6 p. 43.
      Ответить
      • вообще-то в книге это прям рекомендация. Майерс даже назвал это идиомой явной типизации инициализатора.
        Ответить
        • В общем случае, да, он за auto. Конкретно этот случай - иллюстрация "не правильного"(точнее не ожидаемого) вывода типа.
          Ответить
          • иллюстрацией не ожидаемого вывода типа был как раз таки вариант без static_cast'а: auto highPriority = features(w)[5];

            А с явным static_castom всё правильно выводится
            Ответить
            • А можно забить на религию «никогда не пиши типы вручную» и написать:

              bool highPriority = features(w)[5];
              Ответить
              • Да ты чо, в каменном веке застрял штоле.
                Ответить
              • > религию «никогда не пиши типы вручную»
                Вот не понимаю я таких кадров. Ладно бы ещё там был какой-нибудь std::map<std::string, std::vector<std::pair<bool, std::queue<std::string>>>>, а то ведь 4 буквы написать лень! И то, auto и static_cast - не лень.
                Ответить
                • Возможно, если в коде повсеместно используются auto, то bool или int будет смотреться неконгруэнтно и, возможно, будут выбиваться из общей картины. Но доводить программу до того состояния чтобы явно указанный тип выделялся из общей картины - перебор, имо.

                  Вот в выражении типа MyClass *ptr = dynamic_cast<MyClass>(expr()); по факту лучше использовать auto, т.к. иначе идет дублирование. Но это же явное преобразование.
                  Ответить
              • в общем-то потому что так можно я и выложил это на гк )
                Ответить
              • Ну если копнуть глубже, то в каком-то смысле сабжевый код может быть лучше. Он явным образом выражает намерение "скастить результат features(w)[5] в bool" и показывает осведомленность программиста о том, что на самом деле у него там не bool. В то время, как твой код вполне может означать, что автор думает, что результат features(w)[5] - это и есть bool.
                Ответить
                • > автор думает, что результат features(w)[5] - это и есть bool
                  Но ведь это и есть bool.
                  >>> Тип features(w) - std::vector<bool>
                  Ответить
                  • Оп, попался. Нихуя там не бул. std::vector<bool> вообще не контейнер. И никаких bool не содержит.

                    features(w)[5] вернёт прокси-объект, который содержит ссылку на бит в векторе и неявно конвертируется в бул. Из-за такой хуйни использовать его с авто опасно. И не счесть людей, которые сделали const bool& foo = ... и удивлялись, почему код не работает.
                    Ответить
                    • А сделали бы const auto & foo = ... и работало бы!
                      Ответить
                      • Пока не прикрутил бы многопоточность. Потом были бы вопросы типа "почему программу распидорашивает при одновременной записи в различные элементы вектора?".
                        Ответить
                        • Ты сейчас открыл мне глаза на то, что vector<bool> - это действительно ужасное говно.
                          Ответить
                        • Ну и типичные фишки типа &vector[0] чтобы получить доступ к внутреннему массиву не работают
                          Ответить
            • Прошу прощение. Что-то перепутал. Вы правы.
              Ответить

    Добавить комментарий