company_banner

Последние новости о развитии C++

    Недавно в финском городе Оулу завершилась встреча международной рабочей группы WG21 по стандартизации C++, в которой впервые официально участвовали сотрудники Яндекса. На ней утвердили черновой вариант C++17 со множеством новых классов, методов и полезных нововведений языка.



    Во время поездки мы обедали с Бьярне Строуструпом, катались в лифте с Гербом Саттером, жали руку Беману Дейвсу, выходили «подышать воздухом» с Винцентом Боте, обсуждали онлайн-игры с Гором Нишановым, были на приёме в мэрии Оулу и общались с мэром. А ещё мы вместе со всеми с 8:30 до 17:30 работали над новым стандартом C++, зачастую собираясь в 20:00, чтобы ещё четыре часика поработать и успеть добавить пару хороших вещей.

    Теперь мы готовы поделиться с вами «вкусностями» нового стандарта. Всех желающих поглядеть на многопоточные алгоритмы, новые контейнеры, необычные возможности старых контейнеров, «синтаксический сахар» нового чудесного C++, прошу под кат.

    if constexpr (condition)


    В C++17 появилась возможность на этапе компиляции выполнять if:

    template <std::size_t I, class F, class S>
    auto rget(const std::pair<F, S>& p) {
        if constexpr (I == 0) {
            return p.second;
        } else {
            return p.first;
        }
    }
    

    При этом неактиваная ветка ветвления не влияет на определение возвращаемого значения. Другими словами, данный пример скомпилируется и:
    • при вызове rget<0>( std::pair<char*, short>{} ) тип возвращаемого значения будет short;
    • при вызове rget<1>( std::pair<char*, short>{} ) тип возвращаемого значения будет char*.

    T& container::emplace_back(Args&&...)


    Методы emplace_back(Args&&...) для sequence контейнеров теперь возвращают ссылку на созданый элемент:
    // C++11
    some_vector.emplace_back();
    some_vector.back().do_something();
    
    // C++17
    some_vector.emplace_back().do_something();
    

    std::variant<T...>


    Позвольте представить: std::variant<T...> — union, который помнит что хранит.
    std::variant<int, std::string> v;
    v = "Hello word";
    assert(std::get<std::string>(v) == "Hello word");
    v = 17 * 42;
    assert(std::get<0>(v) == 17 * 42);
    

    Дизайн основан на boost::variant, но при этом убраны все известные недочёты последнего:

    • std::variant никогда не аллоцирует память для собственных нужд;
    • множество методов std::variant являются constexpr, так что его можно использовать в constexpr выражениях;
    • std::variant умеет делать emplace;
    • к хранимому значению можно обращаться по индексу или по типу — кому как больше нравится;
    • std::variant не нуждается в boost::static_visitor;
    • std::variant не умеет рекурсивно держать в себе себя (например функционал наподобие `boost::make_recursive_variant<int, std::vector< boost::recursive_variant_ >>::type` убран).

    Многопоточные алгоритмы


    Практически все алгоритмы из заголовочного файла были продублированы в виде версий, принимающих ExecutionPolicy. Теперь, например, можно выполнять алгоритмы многопоточно:
    std::vector<int> v;
    v.reserve(100500 * 1024);
    some_function_that_fills_vector(v);
    
    // Многопоточная сортировка данных
    std::sort(std::execution::par, v.begin(), v.end());
    

    Осторожно: если внутри алгоритма, принимающего ExecutionPolicy, вы кидаете исключение и не ловите его, то программа завершится с вызовом std::terminate():
    std::sort(std::execution::par, v.begin(), v.end(), [](auto left, auto right) {
        if (left==right)
            throw std::logic_error("Equal values are not expected"); // вызовет std::terminate()
    
        return left < right;
    });
    


    Доступ к нодам контейнера


    Давайте напишем многопоточную очередь с приоритетом. Класс очереди должен уметь потокобезопасно сохранять в себе множество значений с помощью метода push и потокобезопасно выдавать значения в определенном порядке с помощью метода pop():
    // C++11
    void push(std::multiset<value_type>&& items) {
        std::unique_lock<std::mutex> lock(values_mutex_);
        for (auto&& val : items) {
            // аллоцирует память, может кидать исключения
            values_.insert(val);
        }
    
        cond_.notify_one();
    }
    
    value_type pop() {
        std::unique_lock<std::mutex> lock(values_mutex_);
        while (values_.empty()) {
            cond_.wait(lock);
        }
    
        // аллоцирет память, может кидать исключения
        value_type ret = *values_.begin();
        // деаллоцирует память
        values_.erase(values_.begin());
    
        return ret;
    }
    
    // C++17
    void push(std::multiset<value_type>&& items) {
        std::unique_lock<std::mutex> lock(values_mutex_);
    
        // не аллоцирует память, не кидает исключения.
        // работает намного быстрее (см. #2)
        values_.merge(std::move(items));
    
        cond_.notify_one();
    }
    
    value_type pop() {
        std::unique_lock<std::mutex> lock(values_mutex_);
        while (values_.empty()) {
            cond_.wait(lock);
        }
    
        // не аллоцирет память и не кидает исключения (см. #2)
        auto node = values_.extract(values_.begin());
        lock.unlock();
    
        // извлекаем значение из ноды multiset'а
        return std::move(node.value());
    }
    

    В C++17 многие контейнеры обзавелись возможностью передавать свои внутренние структуры для хранения данных наружу, обмениваться ими друг с другом без дополнительных копирований и аллокаций. Именно это происходит в методе pop() в примере:
    // Извлекаем из rbtree контейнера его 'ноду' (tree-node)
    auto node = values_.extract(values_.begin());
    
    // Теперь values_ не содрежит в себе первого элемента, этот элемент полностью переехал в node
    // values_mutex_ синхронизирует доступ к values_. раз мы вынули из этого контейнера
    // интересующую нас ноду, для дальнейшей работы с нодой нет необходимости держать блокировку.
    lock.unlock();
    
    // Наружу нам необходимо вернуть только элемент, а не всю ноду. Делаем std::move элемента из ноды.
    return std::move(node.value());
    
    // здесь вызовется деструктор для ноды
    

    Таким образом наша многопоточная очередь в C++17 стала:
    • более производительной — за счёт уменьшения количества динамических аллокаций и уменьшения времени, которое программа проводит в критической секции;
    • более безопасной — за счёт уменьшения количества мест, кидающих исключения, и за счет меньшего количества аллокаций;
    • менее требовательной к памяти.

    Автоматическое определение шаблонных параметров для классов


    В черновик C++17 добавили автоматическое определение шаблонных параметров для шаблонных классов. Это значит, что простые шаблонные классы, конструктор которых явно использует шаблонный параметр, теперь автоматически определяют свой тип:
    Было Стало
    std::pair<int, double> p(17, 42.0);
    std::pair p(17, 42.0);
    std::lock_guard<std::shared_timed_mutex> lck(mut_);
    std::lock_guard lck(mut_);
    std::lock_guard<std::shared_timed_mutex> lck(mut_);
    auto lck = std::lock_guard(mut_);

    std::string_view


    Продолжаем эксурс в дивный мир C++17. Давайте посмотрим на следующую C++11 функцию, печатающую сообщение на экран:
    // C++11
    #include <string>
    void get_vendor_from_id(const std::string& id) { // аллоцирует память, если большой массив символов передан на вход вместо std::string
        std::cout <<
            id.substr(0, id.find_last_of(':')); // аллоцирует память при создании больших подстрок
    }
    
    // TODO: дописать get_vendor_from_id(const char* id) чтобы избавиться от динамической аллокации памяти
    

    В C++17 можно написать лучше:
    // C++17
    #include <string_view>
    void get_vendor_from_id(std::string_view id) { // не аллоцирует память, работает с `const char*`, `char*`, `const std::string&` и т.д.
        std::cout <<
            id.substr(0, id.find_last_of(':')); // не аллоцирует память для подстрок
    }
    

    std::basic_string_view или std::string_view — это класс, не владеющий строкой, но хранящий указатель на начало строки и её размер. Класс пришел в стандарт из Boost, где он назывался boost::basic_string_ref или boost::string_ref.

    std::string_view уже давно обосновался в черновиках C++17, однако именно на последнем собрании было решено исправить его взимодействие с std::string. Теперь файл <string_view> может не подключать файл <string>, за счет чего использование std::string_view становится более легковесным и компиляция программы происходит немного быстрее.

    Рекомендации:
    • используйте единственную функцию, принимающую string_view, вместо перегруженных функций, принимающих const std::string&, const char* и т.д.;
    • передавайте string_view по копии (нет необходимости писать `const string_view& id`, достаточно просто `string_view id`).

    Осторожно: string_view не гарантирует, что строчка, которая в нем хранится, оканчивается на символ '\0', так что не стоит использовать функции наподобие string_view::data() в местах, где необходимо передавать нуль-терминированные строчки.

    if (init; condition)


    Давайте рассмотрим следующий пример функции с критической секцией:
    // C++11
    void foo() {
        // ...
        {
            std::lock_guard<std::mutex> lock(m);
            if (!container.empty()) {
                // do something
            }
        }
        // ...
    }
    

    Многим людям такая конструкция не нравилась, пустые скобки выглядят не очень красиво. Поэтому в C++17 решено было сделать всё красивее:
    // C++17
    void foo() {
        // ...
        if (std::lock_guard lock(m); !container.empty()) {
            // do something
        }
        // ...
    }
    

    В приведенном выше примере переменная lock будет существовать до закрывающей фигурной скобки оператора if.

    Structured bindings


    std::set<int> s;
    // ...
    
    auto [it, ok] = s.insert(42); 
    // Теперь it — итератор на вставленный элемент; ok - bool переменная с результатом.
    if (!ok) {
        throw std::logic_error("42 is already in set");
    }
    s.insert(it, 43);
    // ...
    

    Structured bindings работает не только с std::pair или std::tuple, а с любыми структурами:
    struct my_struct { std::string s; int i; };
    my_struct my_function();
    // ...
    
    auto [str, integer] = my_function();
    

    А ещё...


    В C++17 так же есть:
    • синтаксис наподобие template <auto I> struct my_class{ /*… */ };
    • filesystem — классы и функции для кросплатформенной работы с файловой системой;
    • std::to_chars/std::from_chars — методы для очень быстрых преобразований чисел в строки и строк в числа с использованием C локали;
    • std::has_unique_object_representations <T> — type_trait, помогающий определять «уникальную-представимость» типа в бинарном виде;
    • new для типов с alignment большим, чем стандартный;
    • inline для переменных — если в разных единицах трансляции присутствует переменная с внешней линковкой с одним и тем же именем, то оставить и использовать только одну переменную (без inline будет ошибка линковки);
    • std::not_fn коректно работающий с operator() const&, operator() && и т.д.;
    • зафиксирован порядок выполнения некоторых операций. Например, если есть выражение, содержащее =, то сначала выполнится его правая часть, потом — левая;
    • гарантированный copy elision;
    • огромное количество математических функций;
    • std::string::data(), возвращающий неконстантый char* (УРА!);
    • constexpr для итераторов, std::array и вспомогательных функций (моя фишечка :);
    • явная пометка старья типа std::iterator, std::is_literal_type, std::allocator<void>, std::get_temporary_buffer и т.д. как deprecated;
    • удаление функций, принимающих аллокаторы из std::function;
    • std::any — класс для хранения любых значений;
    • std::optional — класс, хранящий определенное значение, либо флаг, что значения нет;
    • fallthrough, nodiscard, maybe_unused;
    • constexpr лямбды;
    • лямбды с [*this]( /*… */ ){ /*… */ };
    • полиморфные алокаторы — type-erased алокаторы, отличное решение, чтобы передавать свои алокаторы в чужие библиотеки;
    • lock_guard, работающий сразу со множеством мьютексов;
    • многое другое.


    Напоследок


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

    Only registered users can participate in poll. Log in, please.

    Расскажите о чём бы вам было интересно почитать

    • 40.1%Как проходят встречи комитета по стандартизации C++, что сотрудники Яндекса там делали и чего достигли (рассказ о внутренней кухне, а не о новинках C++)217
    • 82.9%Что будет в C++Next (стандарте языка C++, который будет приниматься после C++17)449
    • 43.6%Какие интересные предложения были отправлены на cpp-proposals@yandex-team.ru, какой прогресс у proposals в которых заинтересован Яндекс236
    • 2.9%Другое (расскажу в коментариях)16
    Яндекс
    646.74
    Как мы делаем Яндекс
    Share post

    Similar posts

    Comments 422

      +21
      Хочется думать, что рано или поздно у них руки дойдут и до модулей. Серьезно, я готов недополучить всех этих плюшек, да даже ranges и concepts, лишь бы сделали модули.
        +3
        Модули уже почти готовы (по крайней мере дело дошло до wording — «патча» к существующему стандарту). Если не будет найдено фатальных недостатков, то есть все шансы увидеть модули в C++Next.
          +5
          Да, но это еще минимум до 2020 ждать. Формально. Я конечно надеюсь что хотя бы Microsoft сделают их побыстрее (уже есть подвижки), но хочется везде и немедленно. И в связи с этим куча всяких вопрос: например, сможем ли мы выкинуть на помойку CРР/HPP файлы и просто иметь CPP и всё? Потому что это уже надоело, и самое главное что по стандарту много чего нельзя делать header only, например специализации шаблонов.

          Еще конечно хочется полностью новый STL. Текущая стандартная библиотека мне видится тупиком. Взять хотя бы std::string — на CppNow, Sean Parent рассказывал что у них там 4 реализации строк в коде. А все почему? Потому что обычный API этой строки убогий, а выкинуть и сказать «мы накосячили, давайте заново» никто не готов.
            +1
            Еще конечно хочется полностью новый STL

            В Оулу решено было забронировать все namespace stdцифры для будущего использования стандартной библиотекой. Тоесть когда-нибудь и правда может появиться std2::. У людей в комитете уже сейчас есть идеи для новой версии стандартной библиотеки. Но вот появится она наврядли в ближайшие 10 лет.
              +3
              да уж, 30 лет не могут сделать нормальные строчки — поиск, замена, lower/upper/locale
              30 лет «ходим на костылях», а комитет грезит о дальнем космосе
              запилить строки, синхронизацию, работу с файлами и сетью (+ асинки) — закроет 95% потребностей программистов
              одну либку возмешь, она зависит от boost::asio, другая с необходимыми вещами, что нет в первой — от libevent… кто-то еще притянул ProtoBuf, а еще один решил, что для разных клиентов будет удобнее Thrift(с их сервисами и транспортами)… в итоге в приложении 3-4 либки работы с сетью (неплохо бы еще ZeroMQ с подписками и RabbitMQ для message-queue), 2-3 вида строк и 5-6 реализаций мьютексов и умных указателей… рукалицо/больпечаль

              что касается новой STL из-за строк, то это ты погорячился: достаточно одобрить extension methods и впилить icu-либку, уже будет счастье:
              string toLower( string_view sv ) {… }
              auto str = string(«Hello WORLD!»).toLower();

              offtopic: конечно в узкоспециализированных вещах С++ замены нет, но НЕ для «железного» уровня рассматриваю C++ как низкоуровневую(нативную, шуструю) реализацию некоторых вещей для более удобной/человеческой(созданной для людей) среды, что-то вроде С++ — это интринсики для C#/Java (еще бы их interop был гладкий… мечты)
                +3
                Чёрт бы с поиском-заменой, сами напишем. Дайте поддержку UTF-8 строк! Именно строк как набора символов, а не байт. ЧТоб итерирование работало посимвольно и т. д.
                  +2
                  Есть годные на мой взгляд предложения, но до них не дошли руки и в C++17 их не будет :(
                  +1
                  Поддержка кодировок из коробки — рука лицо, неужели так сложно сделать конвертацию разных кодировок из коробки, и да поддерживаю все что сказано вышел про сеть, строки, я бы ещё рефлекшен попросил( вполне устроили бы флаги компилятора) и аналог protobuff/Thrift, локализацию, стандартные либы типа zlib, libpng, libjpg из коробки, xml парсеры, математические типы, хотябы float3, matrix4x4, quaternion и операции с ними. Мультиметоды ещё хочу, пусть медленные ну да и черт со скоростью.
                  Берешь графический движок, в нем Vector3, берешь физически движок в нет Point3, берешь звуковой в нем float3, берешь либу с поиском пути в ней Float3 и сидишь пишешь бесконечные конвертации точек и матриц из одной либы в другую, со строками такая же бида.
                    +10

                    Cargo. Просто Cargo. И все эти 3 либы будут использовать один набор типов из крейта 3d-geometry.


                    Упс, мы же про С++. Нет, не судьба.

                      0
                      > Берешь графический движок, в нем Vector3, берешь физически движок в нет Point3

                      Строго говоря, Vector и Point — это разные типы данных (даже если одинаковые структуры данных).
                      +2
                      > посимвольно

                      по-code-point-но вы имеете в виду?
                        +6
                        Я думаю он имеет в виду «шоб с русским работало, а все немцы и турки идут в жопу».

                        Но это мысли — интересно в какие слова они облекутся.
                          0
                          Та же Java умеет и так и так. Хочешь — итерируешься по символам (кодпоинты идут… далеко идут), хочешь — по кодпоинтам. В чём трабла сделать аналогично в c++?

                          PS просто не всегда нужно умляуты и прочие радости учитывать при обходе строки (например, если ищешь цифры — то они никакого значения не имеют).
                            +3
                            PS просто не всегда нужно умляуты и прочие радости учитывать при обходе строки (например, если ищешь цифры — то они никакого значения не имеют).
                            Если ищешь цифры (парсишь XML или там JSON), то достаточно работать с байтами если у тебя UTF-8.
                              0
                              Цифры — лишь пример. Вопрос в том, что умляуты и прочие код-поинты, не учитывающиеся как символ для некоторого класса задач не имеют значения. Да и кодировка может быть не одно-четырёх-байтовая UTF-8, а двубайтовый UTF-16.

                              PS под возможной кодировкой я подразумеваю, что для хранения данных в типе строки кодировка (по уму) должна быть одна, но её можно выбирать из разных кодировок, в то же время я знаю две универсальные кодировки — UTF-8 и UTF-16.
                                +1
                                Итерация по символам юникода с полноценной поддержкой большого числа правил ресурсозатратна как по скорости обработки, так и по памяти.

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

                                Я бы вообще не изобретал велосипед, а пользовался исключительно средствами операционной системы. В STL включил бы только врапперы для их вызова. Для основных задач обработки строк этого достаточно. Ну а что касается поддержки экзотических случаев — не стоит ими засорять стандартную библиотеку.
                                  0
                                  Микроконтроллер и С++ 17-года? Ну-ны.
                                  Мне кажется, что все-таки в МК используют либо свой диалект Си, либо некое подмножество современного С++.
                                  Но то что язык идет в тупик — это факт.
                                  (С++ реально крутой, но каждая итерация нового стандарта делает его все монструознее и монструознее)
                                    +3
                                    Проблема в том, что никто не будет писать компилятор именно для какого-то подмножества, да и кто его будет стандартизировать. Поэтому я согласен с DistortNeo в том что раздутая стандартная библиотека имеет минусы — на маленьких контроллерах используется тот же компилятор и тот же язык (разве что системные вызовы из libc и иже с ним по необходимости приходится самостоятельно делать), и C++ там тоже очень полезно использовать, но по мере роста библиотеки, во-первых, будет усложняться портирование, а во-вторых будут учащаться случаи, когда хочется использовать вполне скромный стандартный класс, а он за собой дёрнет iostream — бабах, плюс двести килобайт кода, а на контроллере всего сто двадцать восемь. Языку очень-очень нужны модули и что-то вроде пакетного менеджера, вроде того что у Rust — лучше сподвигнуть людей писать больше лёгких в использовании библиотек, чем засовывать в комплект ещё больше батареек.
                                      +2
                                      Языку очень-очень нужны модули и что-то вроде пакетного менеджера, вроде того что у Rust — лучше сподвигнуть людей писать больше лёгких в использовании библиотек, чем засовывать в комплект ещё больше батареек.
                                      «Батарейки в комплекте» — штука тоже хорошая, но тут у C++ тоже огромная засада: так как каждый тянет одеяло на себя, то в результате в стандарте — очень странная комбинация из вещей, которые мало кому нужны (но зато против которых никто не возражал) и полнейшее отсуствие вещей, которые всем нужны, но про которые каждый хочет чего-то своего.

                                      Простейший пример: ни запустить подпроцесс, ни разобрать параметры, пришедшие в main (с выделеним обязательных/необязательных параметров, etc) средствами стандартной бибилиотки нельзя. Разработчикам систем для микроконтроллеров это, в общем-то и не нужно — но зато нужно всем остальным!
                                        0
                                        std::system запускает подпроцесс. А разбирать параметры, пришедшие в main, можно далеко не единственным способом (как минимум, синтаксис параметров в винде и линуксах разный). И пусть лучше этот парсинг остается в виде отдельных либ, типа boost::program_options
                                          +5
                                          std::system запускает подпроцесс.
                                          Лучше бы он его не запускал. Количество дыр в безопасности, которые образовались из-за того, что в стандарте есть только std::system — не счесть.

                                          Но да, запускает, тут вы правы.

                                          А разбирать параметры, пришедшие в main, можно далеко не единственным способом (как минимум, синтаксис параметров в винде и линуксах разный).
                                          С одной стороны — вы правы: для создания переносимых программ какой-нибудь getopt не годится.

                                          С другой — это значит что сотни тысяч программистов пишут сотни тысяч велосипедов при написании простейших утилит (потому что требование «использовать только стандартуную библиотеку» у заказчиков встречается частенько). Зачем? Ради чего вся эта бурная деятельность?
                                            +1
                                            Представьте себя на месте члена комитета. Вам предлагают стандартизировать реализацию фичи, для которой отсутствуют даже общие соглашения о том, как она должна работать.
                                              +5
                                              А вы представьте себя на месте пользователя, которому нужно что-то простенькое написать — и которого мало волнует наличие «общих соглашений» вокруг фичи.

                                              Я прекрасно понимаю почему члены комитета не могут решить эту проблему — но это не меняет того факта, что конечный результат (огромный и очень сложный язык, который, тем не менее «из коробки» не умеет «элементарных вещей») — очень неприятен.
                                              +2
                                              потому что требование «использовать только стандартуную библиотеку» у заказчиков встречается частенько

                                              Я бы на месте этих программистов старался избегать таких заказчиков с такими немотивированными требованиями.
                                                +2
                                                Требование как раз вполне разумное: код, который не тянет за собой внешних библиотек, легко интегруется куда угодно, код написанный поверх разных сторонних библиотек зачастую интегрировать — та ещё беда.

                                                Никогда не пробовали объединять код, написанный даже не на основе разных библиотек, а на основе всего-навсего всем известного boot'а? Когда один компонент хочет версию 1.20, а другой 1.50… подружить их бывает ох как непросто.
                                                  +1
                                                  Опыт работы с тем же бустом говорит, что для обновления с 1.20 на что-то более новое чаще всего требуются весьма минимальные изменения.

                                                  В худшем случае вы всегда успеете переписать с буста, getopt или чего там ещё на что-то своё. Зато вы сейчас сэкономите больше времени, и сможете его потратить на проработку действительно важных вещей в вашем приложении, а не изобретение ещё одного костыля.

                                                  Вдруг не взлетит, и всё равно выкидывать придётся.
                                        +4
                                        Микроконтроллер и С++ 17-года? Ну-ны.

                                        gcc вроде до сих пор всякие там atmega и прочие attiny поддерживает, разве нет?
                                      +3
                                      Вопрос в том, что умляуты и прочие код-поинты, не учитывающиеся как символ для некоторого класса задач не имеют значения.
                                      Вот я и прошу пример «класса задач». Пока всё, что я видел распадается на два класса: либо оно нормально работает с UTF-8 с побайтовой адресацией, либо адресация по кодпоинтам задачу не решает, а просто загоняет проблему вглубь. Как я написал выше: «шоб с русским работало, а все немцы и турки идут в жопу». Я, в общем, понимаю почему такой подход международный коммитет по стандартизации не очень хочет поддерживать.

                                      PS под возможной кодировкой я подразумеваю, что для хранения данных в типе строки кодировка (по уму) должна быть одна, но её можно выбирать из разных кодировок, в то же время я знаю две универсальные кодировки — UTF-8 и UTF-16.
                                      И опять-таки дихотомия неправильная. Есть два класса кодировок:
                                      1. UTF-8 — кодировка с которой просто работать и расширять языки не нужно
                                      2. Всё остальные кодировки — работать с которыми сложно и потому расширять язык тоже не нужно

                                      UTF-16 относится ко второму классу. UCS-2 (из-за которой в некоторых языках и операционных системах и появилось угробище под названием UTF-16) — да, была проста и красива. Хотя платила за это наличием своих собственных недостатков. UTF-16, увы, имеет все недостатки UTF-8 (один кодпоинт и один элемент строки — разные вещи), но также унаследовала все недостатки USC-2 (например бывает UTF-16LE и UTF-16BE, а это значит что вам нужен BOM и вам нужно знать есть у вас BOM или нет и т.д. и т.п.)

                                      Использовать её нужно только там где есть внешний API, требующий её использования — но наличие внешнего API автоматически обозначает что есть и процедуры для работы с этим творением человеческого разума, а значит иметь API в языке — уже не нужно.
                                        0

                                        Вообще-то, в UTF-8 тоже есть BOM...

                                          0
                                          Гм, можно ссылку? И объяснение, зачем он нужен, заодно?
                                            0

                                            Я так понимаю, он выступает в качестве сигнатуры кодировки. Ссылку не найду.


                                            Но в том же C# любой текстовый файл, записанный в кодировке UTF-8 по умолчанию будет иметь BOM.

                                              +1
                                              Просто BOM — по определению Byte Order Marker. В UTF-8 никакого byte order нет и быть не может, так как единица анализа в нём — один байт. Возможно, очередное гениальное решение Майкрософта?
                                                +2
                                                  +1
                                                  Это размер код поинта, а единица анализа — один байт, и следуют он точно один за другим в одном порядке на любой архитектуре. Проще говоря, парсится UTF-8 побайтово, в отличие от того же UTF-16.
                                                  0
                                                  Именно так. Майкрософт решил его использовать как маркет UTF-8 файла. Но это уже самодеятельность — мало что что ещё можно придумать чтобы жизнь себе усложнить.
                                          +2
                                          Вообще UTF-16 не двубайтовая. Не путайте её c UCS2.
                                    +3
                                    Да, именно так. Чтоб была какая-нибудь функция length, которая возвращает количество code points, и какой-нибудь operator[], который возвращает собственно code point.
                                      +2
                                      Как где-то писал Страустру: «кажется глупым добавлять в язык конструкцию, чуть ли не единственное назначение которой — порождение ошибок определённого класса».
                                    0
                                    Именно строк как набора символов, а не байт.
                                    Можете привести хоть одну задачу, где это реально нужно?

                                    Я знаю много задач где подобный подход породит проблемы (то есть: оно будет работать в простых случаях, но рассыпется нафиг в сложных) и не знаю ни одной практической задачи, где бы это помогало.

                                    P.S. Так, навскидку: не забываем что upcase("ß") == «SS», что upcase(«i») ==«I» у большинства народов, но турков upcase(«i») == "İ" и т.д. и т.п.
                                      0
                                      Это реально нужно в любой задаче, где нужно что угодно делать с не-ASCII текстом. Распарсить XML, например.
                                        +3
                                        Зачем там кодпойнты? Чтобы найти '<', '>', '/', кавычки — про код-пойнты знать не надо, работы «как с ASCII» хватит, так как кусок кодпойнта принять за '<' невозможно. Чтобы понять, пробельный ли символ — тоже. Чтобы сравнить открывающий тег с закрывающим — тоже. Что я не учёл?
                                          0
                                          Например того, что существуют многобайтные кодировки.
                                            +1

                                            Вообще-то тут обсуждались строки в UTF-8, а не в произвольной кодировке.

                                              0
                                              Хватит фигнёй страдать, а? Вы мне реализуйте прототип строки с осмысленным operator[] для ISO-2022, а я посмеюсь. Только про эскейп-символы и связанные с ними радости не забудьте, пожалуйста.
                                                0
                                                Вам для парсинга нужен доступ по произвольному смещению? Если не секрет, то зачем?
                                                  0
                                                  Это то с чего началась данная ветка: дайте, типа, нам посимвольный доступ в UTF-8 строку.

                                                  На вопрос «зачем» ответа так и не последовало, хотя, я на 99% уверен в своей версии: «нам с русским языком работать не удобно, а о немцах, турках и японцах мы думать не хотим — пусть идут куда им захочется… хотят на три буквы, хотят — на пять или десять».

                                                  Как вы понимаете такая мотивировка в международном комитете по стандартизации вряд ли получит движение.
                                                    +1
                                                    Посимвольный произвольный доступ в UTF-8 идея довольно сложно реализуемая. Посимвольный последовательный доступ сделать относительно несложно. В задачах парсинга это как раз очень облегчает жизнь. Для реалистичной по скорости реализации произвольного доступа нужно либо использовать UTF-32, что бьет по памяти, либо UCS-2, но она не покрывает весь юникод.

                                                    По хорошему, строки и символы должны быть отделены от массивов, байтов и кодировок. И уже разработчик будет решать, что ему использовать. Нужны что-то более сложное — вот тебе полноценные строки, но за них придется платить памятью и скоростью. Хотя юникод и поддержка многих языков в любом случае не будет бесплатной.
                                                      0
                                                      По хорошему, строки и символы должны быть отделены от массивов, байтов и кодировок.
                                                      А кто их отделять будет? Вопрос не праздный: Python3 решил пойти по этому пути, что привело к тому, что пользоваться этим ужасом просто невозможно.

                                                      И уже разработчик будет решать, что ему использовать.
                                                      Если бы всё было так просто. Проблема в том, что переход между «потоком байт» (ну, например, именем файла в Linux'е) и «текстом» (ну, например, сообщением «файл «...» имеет размер «...» байт») вовсе не так очевиден как хочется и кажется.

                                                      Нужны что-то более сложное — вот тебе полноценные строки, но за них придется платить памятью и скоростью.
                                                      А что будет если вы отнесёте что-то не в ту категорию? Программисты очень часто не задумывась, относят что-то не в ту категорию — и если у вас есть два жёстко разделённых мира, то исправление этой ошибки — очень дорого. Если у вас и то и другое — строки (подход C++, Go, Python2 и множества других языков) — то жить становится гораздо легче.

                                                      Стандартизация библиотеки для работы с текстом — дело хорошее, только, ради бога, не засовывайте это прямо в язык.
                                                      0
                                                      Это то с чего началась данная ветка: дайте, типа, нам посимвольный доступ в UTF-8 строку. На вопрос «зачем» ответа так и не последовало, хотя, я на 99% уверен в своей версии: «нам с русским языком работать не удобно, а о немцах, турках и японцах мы думать не хотим — пусть идут куда им захочется… хотят на три буквы, хотят — на пять или десять».

                                                      А японцы, которых Вы упомянули, по-Вашему, что UTF-8 — не используют?!
                                                      Это необходимо всем у кого алфавит не на латинице, то есть как минимум 3 миллиардам человек = китайцы + индийцы + японцы + корейцы + таиландцы + пакистанцы + бангладешцы + арабы + и так далее… То есть даже без России — это половина человечества, если не больше, так как в Африке существуют алфавиты тоже основанные не на латинице.
                                                        +3
                                                        Человек убежден в том, что 99% страждущих посимвольный доступ к UTF-8 строкам хотят весьма кривую реализацию, которая будет отлично работать с кириллицей и не работать с иероглифами, немецким и турецким языками и т.п. Ибо эти 99% человек просто не сталкивались с этими проблемами, а потому не представляют, во что превратится нормальная поддержка UTF-8 в стандарте. И я с ним согласен, впихнуть UTF-8 в стандарт — это надо постараться. Да и кому оно ДЕЙСТВИТЕЛЬНО надо?
                                                        Я последние 3 года разрабатываю старый Web-проект с бэкендом на плюсах (+ свой проект тоже на плюсах). Ни разу не было реальной необходимости в посимвольном доступе к UTF-8 строкам.
                                                        В тех же случаях, когда сложная работа с UTF-8 действительно нужна, лучше просто взять специальную библиотеку, а не желать этого в стандарте языка.
                                                        Это примерно как желать 3D движок в стандарте C++. Но что-то я не вижу желающих интегрировать в стандарт, например, OGRE.
                                                          –3
                                                          Стоп. Давайте разделять UTF-8 и Unicode.

                                                          UTF-8 — это просто способ кодирования 31-битных значений в виде последовательности 8-битных байт. Он никак не привязан к смысловому содержанию этих значений.

                                                          Для подавляющего большинства практических задач обработки строк посимвольный доступ (=преобразование UTF8 в UCS2/UCS4 на лету) не нужен — можно работать напрямую с UTF8 представлением строки.

                                                          Если всё-таки нужен произвольный посимвольный доступ, то будет гораздо эффективнее преобразовать строку в массив 2-байтных или 4-байтных значений, а после работы преобразовать обратно. А если ещё хочется и менять значения символов на месте, то как вы себе это представляете для UTF8?
                                                            0
                                                            Ну, работа с текстом требуется куда чаще, чем работа с 3D. Давно уже большая часть приложений не сводится к «продвинутому фортрану».
                                                  0
                                                  Да, вы правы, если в строке интересны только ASCII символы — можно обойтись без понимая UTF-8 и Юникода вообще.
                                                  Но вот мне, например, недавно нужно было искать в тексте кавычки не только обычные, но и “/”, «/», а также символ троеточия.
                                                    +3
                                                    Символ троеточия ищется в UTF-8 как последовательность трёх байт 0xe2 0x80 0xa6 — для этого совершенно не нужны глубины глубин.

                                                    Только сначала прогоните текст один раз через фильтр, убедитесь что это корректный UTF-8…
                                                +2

                                                Если вы пишете текстовый редактор, вам скорее всего потребуется разбивать текст на слова, причём разделителями, как вы понимаете, могут служить не только ASCII-пробелы.


                                                Или если вы пишете компилятор для языка программирования, поддерживающего юникодные спецсимволы (ну как в Mathematica и Haskell), то вам тоже понадобится посимвольный разбор.

                                                  +2
                                                  Если вы пишете текстовый редактор, вам скорее всего потребуется разбивать текст на слова, причём разделителями, как вы понимаете, могут служить не только ASCII-пробелы.
                                                  А ещё их может не быть — совсем. Как в Китайском и Японском, к примеру. И вам всё равно нужно знать на каком языке текст и нужна отдельная процедура, которая этим занимается.

                                                  Или если вы пишете компилятор для языка программирования, поддерживающего юникодные спецсимволы (ну как в Mathematica и Haskell), то вам тоже понадобится посимвольный разбор.
                                                  Зачем? Если вам достаточно «халтурной» реализации — посимвольной обработки хватит. А если вы хотите полноценную поддержку, то тут всё сложнее. Нужно как-то обрабатывать LTR, возможно придётся как-то озаботиться сравнением Hangul Syllables и Hangul Jamo и прочее.
                                                    0
                                                    А ещё их может не быть — совсем. Как в Китайском и Японском, к примеру.

                                                    Не понял, чего нет в китайском и японском? Пробелов?


                                                    И вам всё равно нужно знать на каком языке текст и нужна отдельная процедура, которая этим занимается.

                                                    Ну в этой-то отдельной процедуре настоящие юникодные строки вам будут нужны, так ведь?

                                                      +1
                                                      Не понял, чего нет в китайском и японском? Пробелов?
                                                      Угу. Для того, чтобы понять где можно переносить строку нужно использовать достаточно сложный алгоритм, содержащий, среди прочего, ещё и словарь иероглифов…

                                                      Ну в этой-то отдельной процедуре настоящие юникодные строки вам будут нужны, так ведь?
                                                      Скорее нет, чем да. Оперировать с отдельными символами вам там нужно будет очень редко, вполне достаточно требования что на входе — корректная UTF-8 строка. Вот это — да, нужно чётко отделять уровни где у вас std::string — это ещё «поток байт» и уровни где это уже текст (==корректный UTF-8).
                                              –5

                                              Со строками например такая проблема: у строки есть и size() и length(). Вот представьте вы начинающий разработчик, хотите понять что это за функции такие? Интуиция как бы подсказывает, что length = количество буков (символов), а size = размер "сколько вешать в байтах". Но не тут-то было. К тому же, в упор непонятно, почему это length() — функция, а не свойство строки. Но это уже другая история.


                                              Про UTF-8 я вообще помалчиваю. Мне бы хоть ASCII но с вменяемым синтаксисом. Где split(), to_lower(), и прочие очевидные вещи? Почему я использую Boost на каждый чих? Ведь Boost — это глобальные функции, а это полная отсутствие discoverability, то есть, есть у вас IDE, нет ее, не важно, т.к. комплишн по всем глобальным символам еще-не-заимпортированных заголовков не сделать в принципе.


                                              Экстеншн-функции — хорошая, проверенная в C# тема, но с ней тоже как-то не торопятся. А даже если сделают, мы что, будем стандартизировать эти "патчи" стандартным типам? Или каждый тихо в гараже запилит свой split() и его будет шипить как сорцы?


                                              Вообщем, проблем много.

                                                +16
                                                К тому же, в упор непонятно, почему это length() — функция, а не свойство строки.

                                                Потому что в C++ нет свойств? Или я что-то пропустил?

                                                  +1

                                                  "Стандартный" split должен быть эффективен и широко применим. Есть n3593 с довольно адекватной мотивацией. Ждёт как раз упоминаемых string_view и Ranges.

                                                    +3
                                                    Народ просто, похоже, не понимает, что большинство этих «ненужных» фич принимается именно для того, чтобы была возможность нормально имплементировать широко используемые фичи в стандартной библиотеке. Например, нормальные умные указатели были невозможно без мув-семантики, туплы — без вариадик темплейтов. Отсутствие же вариадик темплейтов не позволило имплементировать аналог printf-а, что привело к возникновению стримов — единственного возможного решения для типизированного ввода-вывода в таких условиях.
                                                      0
                                                      Понимают, но оптимизация в прикладном коде, к сожалению, не возникнет сама собой и везде. Выходит для того, чтобы пользовательский класс стал «эффективным» в рамках STL, народу также нужно разбираться во всех тонкостях и особенностях реализации стандартной библиотеки, а это, учитывая размер разбухающего стандарта, уже слишком, на мой взгляд…
                                                  –5
                                                  30 лет не могут сделать нормальные строчки — поиск, замена, lower/upper/locale
                                                  30 лет «ходим на костылях», а комитет грезит о дальнем космосе
                                                  запилить строки, синхронизацию, работу с файлами и сетью (+ асинки) — закроет 95% потребностей программистов

                                                  Точно вместо удовлетворения необходимостей, комитет занимается тем что блаженно чешет своё ЧСВ. :(

                                                  PS создайте кто-нибудь петицию на Change.org чтобы до этих зажравшихся козлов в комитете наконец дошло!
                                                    +3
                                                    Лучше сразу на roi.ru
                                                      +2
                                                      Почему не в спортлото?
                                                    +1
                                                    Модули — это основная причина, делающая крайне затруднительным использование стороннего кода и невозможным — менеджеров пакетов. Кстати, экспериментальная реализация модулей уже есть в Visual Studio 2015 Update 2. Но она настолько сырая, что пользоваться ею не хочется совсем.

                                                    STL ужасен до невозможности после опыта работы с более новыми языками с нормальными библиотеками. Больше всего бесит широкое использование беззнаковых типов и смешение знаковых/беззнаковых. Затем — ужасный iostream с нелогичными перегрузками и форматированием. В качестве прикола пытался написать аналог .NET String на C++ с SubString (с указателями), особенно String.Format с variadic templates. Даже работало и было на порядок удобнее printf и тем более cout.
                                                      0
                                                      Хм, имелось в виду «отсутствие модулей» — плохо.
                                                      И я очень надеюсь, что с введением модулей будет полностью переработана STL.
                                                        0

                                                        Я вот думаю, так под шумок модулей можно и STL переписать. Но это скорее мечты.

                                                          +4
                                                          Основная проблема в том, что одним из столпов С++ является обратная совместимость: если кто-то 10 лет назад использовал какую-либо функцию, то её уже не удалить из стандарта. А превращать язык в снежный ком никто не хочет.
                                                            0
                                                            Есть же примеры такие как auto_ptr и не COW-строк в последних stdlibc++
                                                              0

                                                              auto_ptr до сих пор поддерживается, а не COW-строки в GCC начали разрабатываться за много лет до появления стандарта (оказалось что COW-строки на многопроцессорных системах сильно медленнее, а экономия памяти редко когда стреляет).


                                                              Если вы не обнаружилось что из распространённых компиляторов только один использует COW-строки, да и тот планирует «при удобном случае» от них отказаться — фиг бы чего вышло. Да и то: это изменение старые программы не поломало, максимум — изменило потребление памяти.
                                                                0
                                                                И когда-то auto_ptr из стандарта совсем уберут, как убирают std::binary_function из c++17, то есть при указании -std=c++17 он не будет определён.

                                                                Реализацию, наверное, не template-функций убрать из библотеки будет сложно, но никто в приципе не мешает старым программам требовать старую stdlib.

                                                                А насчёт COW — это я имел ввиду то, что бинарную совместимость тоже иногда ломают.
                                                                  0
                                                                  А насчёт COW — это я имел ввиду то, что бинарную совместимость тоже иногда ломают.
                                                                  А тут как раз очень забавно. У Microsoft'а она вообще ломается каждую версию, а в Linux'е введение не-COW строк, строго говоря, бинарную совместимость не сломало. Тeперь в стандартной библиотеке есть std::string и std::__cxx11:string — и, в теории, ничто не мешает библиотекам и программам продолжать поддерживать и использовать оба вида строк…
                                                                    0
                                                                    Ну нет, всё-таки одновременно два типа строк смешивать не получится нормлаьно, там же сигнатуры разные. Только если через c-интерфейс.

                                                                    Но вообще вся моя идея была в том что функдамент миграции на новые бинарные и не совсем реализации заложен и вполне себе используется, так что я не очень удивлюсь если когда-то будут совсем выкидывать старые куски, требуя использовать старые компиляторы/библиотеки если что не так.

                                                                    А сейчас нет чего-нибудь что требует страый gcc для сборки?
                                                                      0
                                                                      А сейчас нет чего-нибудь что требует страый gcc для сборки?
                                                                      Старые программы испольщующие, скажем, iostream.h? Это, кажется, самое заметное несовместимое изменение…

                                                                      Предыдущие «циклы» (переход с GCC 2.95 на GCC 3 и с GCC 3 на GCC 3.4+), кажется все уже и забыли…
                                                                      0
                                                                      > а в Linux'е введение не-COW строк, строго говоря, бинарную совместимость не сломало.
                                                                      Строго говоря как раз таки сломало.
                                                                      Если разные модули будут использовать в своих API stl строки, и будут собраны в режиме С++11, но один компилятором GCC-4.*, а второй — GCC-5 и выше, то они будут ABI не совместимы.
                                                                        0
                                                                        Если разные модули будут использовать в своих API stl строки, и будут собраны в режиме С++11, но один компилятором GCC-4.*, а второй — GCC-5 и выше, то они будут ABI не совместимы.
                                                                        Зависит от того — как именно вы используете GCC-5. Вы можете им собрать свою библиотеку с std::string, с std::__cxx11:string и даже с обоими вариантами одновременно.
                                                                          +2
                                                                          > Зависит от того — как именно вы используете GCC-5
                                                                          В общем случае нет, не зависит.
                                                                          Собрать то свою библиотеку я действительно могу как угодно, но если какая-либо библиотека уже собрана (например, компонент без исходников) пусть в gcc-4.9, а в дистрибутиве линукса установлен gcc-5+ (с новым ABI по умолчанию), то эта библиотека будет не совместима с поставляемыми в дистрибутиве другими библиотеками (они то используют std::__cxx11:string вместо std::string).

                                                                          По Вашей ссылке об этой проблеме тоже написано:
                                                                          > If the third-party library cannot be rebuilt with the new ABI then you will need to recompile your code with the old ABI.
                                                                          А «your code» вполне может быть и энное количество поставляемых в системе библиотек.
                                                                          Какая же это совместимость ABI, если требуется «recompile your code with the old ABI»?
                                                        +1

                                                        В Clang модули реализованы уже несколько лет (правда не совсем тот вариант что пошёл в стандарт).

                                                        0
                                                        Рад слышать! Тоже очень жду модулей!
                                                        А где можно почитать «почти готовый» стандарт про них? Интересно, как он выглядит на данный момент.
                                                      +5
                                                      Мне все интересно! Пишите больше, это очень интересная тема.
                                                      Некоторые мысли по статье
                                                      1. Как «if (init; condition)» будет взаимодействовать с объявлением переменных внутри круглых скобок if, т.е. «if(int x = foo())»?
                                                      Кстати, сама по себе форма уже очень близка вот к этому https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html, т.е. к тому чтобы сделать стейтменты выражениями, как в Scala или Nemerle.
                                                      2. Structured bindings… получается очень забавно — в С++ со всех сторон подошли к прямой реализации кортежей средствами языка, но видимо из-за «legacy» синтаксических особенностей так и не сделают. А так почти все есть — и списки инициализации, и pair/tuple, и вот теперь structured bindings…
                                                        0
                                                        1. Как «if (init; condition)» будет взаимодействовать с объявлением переменных внутри круглых скобок if, т.е. «if(int x = foo())»?

                                                        Если нет `;` в `if`, то считается что в круглых скобках condition. Другими словами — работать будет так же, как сейчас.

                                                        2. Structured bindings… получается очень забавно — в С++ со всех сторон подошли к прямой реализации кортежей средствами языка, но видимо из-за «legacy» синтаксических особенностей так и не сделают. А так почти все есть — и списки инициализации, и pair/tuple, и вот теперь structured bindings…

                                                        Одно из предложений, которые обсуждали на собрании, как раз было что-то похожее на «кортежы средствами языка». Но это был скорее исследовательский доклад, и решено было пока продолжить исследования и посмотреть что получится.
                                                          0
                                                          А если я там напишу более двух стейтментов? if( foo(); bar(); baz(); condition )
                                                          Интересны пределы возможностей, так как реально это очень похоже на возможность использования цепочки стейтментов в выражении.
                                                          Кстати, «if constexpr» это небось из D «static if» таки протащили?
                                                            +1
                                                            Ну не удивительно, т.к. Александреску позиционировал static if как основное преимущество D.
                                                              0
                                                              static if кроме как для шаблонов где-то нужен?
                                                                0

                                                                ну фактически static if заменяет некую функциональность как шаблонов так и макросов, т.е. может быть использован для условной компиляции и метапрограммирования.

                                                                  +1
                                                                  Компилятор выкинет тождественные if'ы даже если они не помечены как constexpr. Суть в том, чтобы подавленная ветка даже не компилировалась.
                                                              +2
                                                              Тем самым возможно иметь два различных объявления внутри if стэйтмента:
                                                              if (int x = foo();  double y = bar());
                                                              

                                                              А также вместо инит стэймента может быть экспрешн стэйтмент:
                                                              if (do_something(); int x = foo());
                                                              

                                                              Кстати, кланг уже поддерживает эту фичу (спасибо мне и Ричарду Смиту :)
                                                                0
                                                                А expression-statement — это для lock-guards, или для чего-то ещё?
                                                            +3
                                                            Видимо в бусте закончились фичи которые можно спереть в стандарт.
                                                              +1
                                                              Фичей ещё очень много :)
                                                              Просто комитет не занят стандартизацией только библиотек Boost.
                                                                +11
                                                                Непонятно чем он вообще занят. Импортов нет, концептов нет, filesystem нет. Даже pragma once(или ее аналог) не могут в язык внести.
                                                                  +4

                                                                  filesystem вообще-то есть.

                                                                    +2
                                                                    Даже pragma once(или ее аналог) не могут в язык внести.

                                                                    Может, потому что эту «фичу» невозможно корректно имплементировать? Уже сто раз оговорено, что pragma once не должна использоваться в нормальном коде.
                                                                      0

                                                                      Можно ещё раз для тех, кто всё пропустил? Хотя бы ссылку. Потому что у нас pragma once используется и не вызывает никаких проблем, а кодовая база собирается разными компиляторами.

                                                                        +2
                                                                        Если коротко, при использовании pragma once компилятор должен уметь корректно определять уникальность файла, что в общем случае невозможно из-за большого количества файловых систем и их особенностей. Самое простое, возможны ошибки при использовании символических или хард ссылок на один и тот же файл, которые могут генерироваться в процессе построения проекта и тп.
                                                                          +1

                                                                          У систем сборки (того же make, к примеру) есть точно такая же проблема — они не могут различать артефакты (цели) по символическим ссылкам в общем случае.


                                                                          Означает ли это, что системы сборки на основе артефактов не следует использовать? Нет, не означает. Это означает что всевозможные ссылки надо использовать осторожно.


                                                                          И с pragma once то же самое.

                                                                            +1
                                                                            И с pragma once то же самое.
                                                                            Нет, не то же самое. Систем сборки не страдающих от указанных вами проблем я не видел (для языков без модулей, в общем-то, и альтернатив не придумать), а для pragma once альтернатива есть, описана в стандарте и работает ничуть не хуже.
                                                                              0
                                                                              Систем сборки не страдающих от указанных вами проблем я не видел

                                                                              Хм, вроде как SCons по умолчанию использует md5 по содержимому файла для определения его уникальности. Вроде это должно помочь при сложностях со ссылками.

                                                                                0
                                                                                Хм, вроде как SCons по умолчанию использует md5 по содержимому файла для определения его уникальности.
                                                                                Если бы SCons этим занимался, то он бы обрабатывал мало-мальски сложные проекты невменяемо долго. MD5 Scons использует, но уже после проверок на изменение даты. Если файл изменится, а дата модификации и размер останутся неизменными — SCons ничего не заметит…

                                                                                Всё просто: посмотреть на метаинформацию можно даже если у вас в проекте сотни тысяч файлов. А делать что-то другое — слишком накладно если у вас исходников достаточно много.
                                                                                  +1
                                                                                  Если бы SCons этим занимался, то он бы обрабатывал мало-мальски сложные проекты невменяемо долго

                                                                                  Это очень похоже на мое о нем впечатление)


                                                                                  Смотрю в доках:


                                                                                  By default, SCons keeps track of whether a file has changed based on an MD5 checksum of the file's contents, not the file's modification time.

                                                                                  И судя по тем же докам, проверка времени изменения перед проверкой хешей опциональна и требует явного включения — Decider('MD5-timestamp').

                                                                            0

                                                                            Спасибо.


                                                                            Из любопытства заглянул в исходники Clang: там и правда инклюд гарды используются. Тем не менее, все популярные компиляторы эту прагму поддерживают ведь. И я как-то не встречал рекомендаций от неё отказываться. Если она такая проблемная и это "общепризнанно", то могли бы хотя бы предупреждение выдавать.

                                                                              0
                                                                              GCC первоначально выдавал предупреждение об отключении pragma once, если компилируемый код использовал её. Тем не менее, в релизе 3.4 GCC код обработки команды pragma once был исправлен для корректной работы с символьными и жёсткими ссылками. Данная возможность была сочтена полезной и предупреждение было убрано
                                                                              https://ru.wikipedia.org/wiki/Pragma_once
                                                                                +2

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

                                                                                  +4
                                                                                  Она не то чтобы очень проблемная, в большинстве случаев она работает так как надо. Вот только вносить в стандарт то что «в большинстве случаев работает так как надо» — плохое решение. К тому же сама возможность полностью корректной имплементации под вопросом, и при этом есть решение, лишённое недостатков pragma once. Поэтому отсутствие её в стандарте — закономерно и правильно, как по мне.
                                                                                    +1

                                                                                    Справедливости ради, у решения "лишённого недостатков pragma once" есть свои недостатки, пусть и незначительные. Например, необходимость вручную следить за уникальностью имён, хотя заранее соглашусь, что это не особо сложно.

                                                                                      0
                                                                                      Ну, программисту за многим приходится следить самому — например, за уникальностью имён переменных, классов и функций, так что я не стал бы причислять это к серьёзным недостаткам.
                                                                                        +4

                                                                                        Ну нет, вот за этим, как правило, как раз следить не надо (если не брать отдельные хитрые моменты): при создании одноимённого класса/функции компилятор честно выдаст ошибку.


                                                                                        Повторюсь — я не считаю, что проблема уникальности именования гардов сколь-нибудь остро стоит. Но лично мне всегда приятно когда за разными мелочами следит компилятор, а не самому требуется внимательность проявлять. По крайней мере, если автоматика не приносит свои особенности/недостатки.

                                                                                          –1
                                                                                          при создании одноимённого класса/функции компилятор честно выдаст ошибку.
                                                                                          При использовании одномённых гардов — тоже. Теоретически можно придумать код, который не вызоват ошибку при коллизии, а приведёт к неправильной работе — ну так и с именами функций такая фигня бывает.

                                                                                          Но лично мне всегда приятно когда за разными мелочами следит компилятор, а не самому требуется внимательность проявлять.
                                                                                          presubmit-скрипт решает это проблему…
                                                                                            +2

                                                                                            При использовании одномённых гардов компилятор ошибку, конечно, выдаст — но найти ее причину будет не проще чем найти #define true false. Потому что компилятор попросту не включит один из двух конфликтующих заголовочный файлов — и потом выдаст кучу воплей о необъявленных типах и функциях.

                                                                                              +2
                                                                                              Да. И с такими проблемами «в продакшене» я сталкивался, особенно при рефакторинге. С проблемами с прагмами я не сталкивался ни разу.
                                                                              0
                                                                              Почему бы тогда не позволить #pragma once(MY_HEADER), которая была бы «сахаром» для

                                                                              #ifndef MY_HEADER_#FILEHASH#
                                                                              #define MY_HEADER_#FILEHASH#

                                                                              #endif?
                                                                                0
                                                                                Потому что это решение — хуже существующего. Например потому что существующее решение не зависит от хеша файла.

                                                                                P.S. Когда может оказаться полезным трактовать разные файлы как одинаковые? Когда это — разные версии одного и того же файла.

                                                                                P.P.S. Я не говорю что существующее решение — идеально. Но так как все «простые решения» имеют свои подводные камни, то лучше не пытаться забить очередной костыль (который всего лишь заменит одну проблему другой), а всё-таки подумать на тему модулей. Ну не создают нормальные люди новые файлы так часто, чтобы эти три строчки были проблемой, не создают!
                                                                                  –1
                                                                                  Генерите уникальный GUID на каждый новый файл. Всё, проблемы больше нет.
                                                                                    +1

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

                                                                    +2
                                                                    inline для переменных — если в разных единицах трансляции присутствует переменная с внешней линковкой с одним и тем же именем, то оставить и использовать только одну переменную (без inline будет ошибка линковки);


                                                                    Извините, но это капитальнейшая подстава и здоровенная пуха, которая теперь будет отстреливать ноги всем и по самую шею!

                                                                      +1
                                                                      сейчас линкер так работает для шаблонов. в чем будет заключаться подстава и не для шаблонов тоже?
                                                                      иногда CPP-файл создается просто для того, чтобы в нем определить переменные… уныло
                                                                        +1

                                                                        Проблема в том, что можно схлопотать алиасинг на одну переменную там, где это не нужно. Для шаблонов это работает вынужденно.

                                                                        0
                                                                        Чтобы так «пальнуться» надо написать что-то типа inline int a = ...; в двух .cpp вне классов/методов/неймспейсов. Нечаянно взломать сейф, так сказать
                                                                          0

                                                                          Не-а. Надо как раз забыть у статик-переменной дописать static, который сделает ей локальную видимость.

                                                                        +1
                                                                        std::string_view

                                                                        std::array_view я так понимаю не будет?

                                                                          0
                                                                          В C++17 не будет, но есть надежда что скоро появится в std::experimental::
                                                                            –1

                                                                            Тут кстати интересная дуальность. Везде в STL у нас обобщенные алгоритмы которые берут begin()/end() не важно откуда. А для строк почему-то свой string_view хотя по логике вещей могли бы дать и array_view и сказать "а дальше вы сами". Ведь по сути, пока нет поддержки юникода, строки и массивы — это одно и то же :)

                                                                              +3

                                                                              Во-первых, у begin-end нельзя взять ни длину, ни подмассив указанного размера.
                                                                              Во-вторых, при сшивании со старым кодом часто нужно передать пачку элементов непрерывным буфером. begin-end тоже пасуют.
                                                                              По поводу же строк, у них есть ряд методов, которых нет у не-строковых срезов.


                                                                              Ну и наконец, моё сугубо личное мнение, что сама по себе идея делать 2 итератора на диапазон, да ещё и требовать от них совместимости по интерфейсу с указателями, была отвратительной. Потому что реально в случае с RandomAccessIterator, например, у нас не 2 итератора, а слайс — убого скрытый под 2-мя итераторами. А теперь городим костыли в виде разнотипных итераторов. И, кстати, в stdlib до сих пор нет шаблонов для конструирования этих самых итераторов.

                                                                                0

                                                                                Ну, если на то пошло, давайте признаемся что в современном мире более рационально сделать некий интерфейс IEnumerable<T> (привет C#) и поддержать ключевое слово yield, которое дает возможность произвольно возвращать коллекцию даже тогда, когда это дерево и нужна рекурсия. В С++ сейчас писать итератор для дерева в рекурсивном стиле невозможно.


                                                                                А потом можно передавать не begin()/end() а просто сам объект. И все счастливы.

                                                                                  +8

                                                                                  Примерно так и есть. Сделано, кстати, в одном языке на R, 4 буквы в названии. Ооочень удобно, даже без yield — когда итерирование по коллекции — 1 метод, а не как минимум 3-4.

                                                                                    +3
                                                                                    Что за язык? Ravascript? Rwift? Rython? Не томите!
                                                                                      +2

                                                                                      Rust вообще-то. Почитайте на досуге, если интресно. Там, в частности, исправлены многие косяки С++.

                                                                                        +1
                                                                                        А можно от несогласных пояснение, где я не прав? Или в споре о С++ другие языки и, в частности, потенциальных конкурентов, упоминать запрещено?
                                                                                          0

                                                                                          Ну… евангелизм бывает навязчивым. (:


                                                                                          Если что, мне самому раст очень интересен, так что минусов не ставил, даже наоборот.

                                                                                            +2
                                                                                            Потерпите пару годков. Go тоже несколько лет назад усиленно PRили. Потом успоколились. Сейчас вот Swift и Rust.

                                                                                            P.S. Swift меня не волнует от слова никак — точно так же, как не волнует, скажем, язык 1С (зачем мне язык намертво завязанный на чужую экосистему?), а на Rust — я поглядываю, но пока не решился ничего серьёзного на нём писать.
                                                                                              +1

                                                                                              Меня пиар раста не раздражает, просто понимаю людей, которые недовольны тем, что его рекламируют в темах про совсем другой язык.

                                                                                              +2

                                                                                              Бывает. Впрочем, я не евангелист — так, сочувствующий. Стараюсь если вставлять про Rust, то по теме обсуждения и понемногу. И давайте наверное закрывать эту ветку, а то совсем оффтоп получается.

                                                                                    0
                                                                                    есть функция std::distance, который как раз выдаст длину контейнера, определяемого итераторами begin и end. Точно так же у большинства контейнеров определен конструктор, принимающий итераторы и возвращающий, по факту, подмассив указанного размера: std::wstring ws = L«sometext»; std::string s(ws.begin()+4, ws.end()); вернет «text»
                                                                                      +1
                                                                                      Проблема в том, что в общем случае очень трудно определить, какая категория итераторов пришла. Да просто нет возможности поставить ограничение «здесь принимается random access iterator».
                                                                                      Плюс, ограничение на тип элемента делается криво.
                                                                                      Плюс, функции, принимающие итератор, обязаны быть шаблонными — а принимающие срез конкретного типа — нет.

                                                                                      В общем, пользоваться можно — но срезы удобней.
                                                                                        +1
                                                                                        Почему же трудно то?
                                                                                        template std::enable_if_t<std::is_same<std::random_access_iterator_tag, typename T::iterator_category>::value,void>
                                                                                        doSomething(T begin, T end) { /*...*/ }
                                                                                        Вот вам и ограничение «здесь принимается random access iterator».

                                                                                        Шаблонность в общем случае тоже необязательно — можно пользоваться auto функциями/лямбдами
                                                                                          +2

                                                                                          Сравните с


                                                                                          void doSomething(stdext::slice<int> someslice) { ... }

                                                                                          1. Нет enable_if_t. Который в большинстве случаев применяется как костыль в отсутствии концептов
                                                                                          2. Нет шаблонности — можно имплементацию прятать в другой модуль.
                                                                                          3. Банально легче читать
                                                                                            0
                                                                                            я доказывал только реализуемость
                                                                                              0

                                                                                              Так я тоже писал, что возможно — но неудобно.

                                                                                +2
                                                                                std::variant

                                                                                Они таки вставили null state. Не очень хорошо, честно говоря. Я так понимаю, это жертва для обеспечения exception safety. Хотя могли бы потребовать noexcept для деструкторов и move конструкторов.

                                                                                  0
                                                                                  Они таки вставили null state.

                                                                                  Да, он называется valueless_by_exception() и возникает крайне редко.

                                                                                  Хотя могли бы потребовать noexcept для деструкторов и move конструкторов.

                                                                                  Есть много вариантов как реализовать std::variant, у всех есть свои недостатки. Мне нравилась версия «требовать noexcept default constructor для хотябы одного типа». Но у этой версии большие проблемы с юзабилити, так что std::variant с valueless_by_exception() намного более юзабельный.
                                                                                    0

                                                                                    Не в курсе, к сожалению. Реализовывал свой велосипедик на эту тему, чтобы работал на GCC 4.9 и не аллоцировал память. В результате пришёл к двум ограничениям — noexcept destructor и noexcept move constructor. На их основе можно делать variant который или будет всегда в валидном состоянии, или уронит программу std::terminate. Оба ограничения как по мне вполне адекватные. Кидаться исключениями из деструктора нехорошо, а из мув-конструктора — просто глупо. Кстати, noexcept default ctor в таком случае не нужен.

                                                                                      +1

                                                                                      Проблема в том, что в обычной жизни есть довольно много типов без noexcept move коонструктора. Некоторые стандартные контейнеры например.

                                                                                        +3

                                                                                        Вот кстати не могу представить throwing move. Подкинете пример?

                                                                                          0
                                                                                          Например один из вспомогательных компонентов boost::variant имеет потенциальный throwing move.
                                                                                            +1

                                                                                            По-моему, аллокация памяти там сильно лишняя. Почему не могут просто отдать буфер? Ведь, по сути, recursive_wrapper почти то же самое, что и unique_ptr.

                                                                                              0
                                                                                              Если без неё, то становится намного хуже. recursive_wrapper отличается от unique_ptr тем, что не должен хранить nullptr. По смыслу recursive_wrapper — это ссылка, а не указатель.

                                                                                              Если разрешить ему хранить nullptr и кидать исключение при разименоввывании (а его разименоввывание происходит внутри variant и скрыто от пользователя), то variant теряет never-empty guarantee и иногда начинает хранить пустой recursive_wrapper. В итоге получается нечто среднее между boost::variant и std::variant, чего всячески хочется избежать.
                                                                                  +1
                                                                                  Комбинация structured bindings и if (init; condition) очень вкусно смотрится:

                                                                                  if (auto [x, y] = foo(); y == something) {… }

                                                                                  Как я понимаю, переменные, объявленные в секции init, существуют и внутри else тоже?
                                                                                    +3
                                                                                    Да, внутри else тоже существуют. А ещё эта конструкция применима и к switch:
                                                                                    switch (auto [x, y] = foo(); y) {
                                                                                    case 1: x += 10; break;
                                                                                    // ....
                                                                                    default: x = 0;
                                                                                    }
                                                                                    
                                                                                      +1
                                                                                      Хм… А до такого когда-нибудь доведут, интересно:
                                                                                      switch (foo()) {
                                                                                      case [true, result]:
                                                                                      do_something(result);
                                                                                      break;
                                                                                      case [false, _]:
                                                                                      LOG(error)
                                                                                        +3
                                                                                        Хм… А до такого когда-нибудь доведут, интересно:
                                                                                        switch (foo()) {
                                                                                        case [true, result]:
                                                                                            do_something(result);
                                                                                            break;
                                                                                        case [false, _]:
                                                                                            LOG(error) << "Shit happens!";
                                                                                            break;
                                                                                        }


                                                                                        Кстати, а плейсхолдеры добавили? Желательно что-нибудь минималистичное вроде того же "_", а не «std::structured_bindings::paceholders» 8)) И алиасы нподобие хаскеллевского «pair@(first, second)»? Понятно, что это сахарок, но без него таки не так сладко будет.

                                                                                        PS: прошу прощения, в прошлом комментарии что-то с форматированием стряслось…
                                                                                          +1
                                                                                          так можно же писать using std::placeholders;
                                                                                            0
                                                                                            Ну тогда уж using _ = std::unused. И, к слову сказать, ещё вот какую-нибудь такую штуку было бы приятно иметь a-la designated inits:
                                                                                            auto [st_size: sz, st_mode: mode] = fstat_wrapper(fd);
                                                                                            if (S_ISREG(mode) && sz > 0xfffffffful)
                                                                                                std::cerr << "Ooops.\n";
                                                                                            
                                                                                        0
                                                                                        А теперь хочется чего-то вроде

                                                                                        if ( auto [x, y, z] = [foo(), bar(), baz()]; y == something ) { }
                                                                                        
                                                                                          +2

                                                                                          Так уже можно, используя std::tuple и новую возможность вывода аргументов шаблонов для классов:


                                                                                              if ( auto [x, y, z] = std::tuple(foo(), bar(), baz()); y == something ) { }
                                                                                        +7
                                                                                        Очень интересно влияет ли развитие Rust на идеи участников комитета и обсуждается ли он? Да и вообще очень волнительно как один из любимых языков будет развиваться когда рядом есть такой конкурент как Rust, да еще учитывая новости о том, что его начали использовать в Dropbox, переписывать на нем отдельные части в Firefox и т.д. Просто раньше как то все было проще и понятней, был C и С++, и практически подавляющее большинство задач системного программирования решалось на них, но теперь то все эти задачи можно точно так же решать и на Rust с его вроде как передовыми идеями, и что дальше?
                                                                                          +19
                                                                                          Безобразное усложнение С++ волей-неволей заставляет смотреть в сторону Rust.
                                                                                            +2
                                                                                            Судя по небольшому личному общению: они замечают тот уровень маркетинга, который обеспечивает себе Rust, но его фичи как таковые их не беспокоят т.к. большинство из них потребуют переделывания либо С++ либо стандартной библиотеки, а они не готовы ни к тому ни к другому.
                                                                                              +2
                                                                                              Думаю к моменту выхода C++20 никакой С++ будет уже не нужен.
                                                                                                +9
                                                                                                С тем же успехом можно сказать, что к моменту выхода С++20 уже никакой Rust будет не нужен.
                                                                                                  +5
                                                                                                  Шел 2196-й год… С++ праздновал свой двухсотый день рождения новым стандартом, а его всё хоронили и хоронили…
                                                                                                    +2
                                                                                                    Как дельфист: добро пожаловать!
                                                                                                      –2
                                                                                                      это уже впору называть каким-нибудь «синдромом флешплеера» — его убивают, а он все чето никак.
                                                                                                      а Rust не будет конкурентом плюсам, пока к нему не будут разжеваны и задокументированы все шаблоны проектирования, иначе два из трех интересующихся будут отпадать в борьбе с компилятором.
                                                                                                        +2
                                                                                                        Между «похоронили» и «популярен» есть еще много промежуточных состояний.
                                                                                                        Они больше не популярны, количество вакансий снижается, почти не развиваются, сообщество растворяется.

                                                                                                        Тот же флешплеер работает сейчас в лучшем случае на трети устройств.
                                                                                                        Не вижу у этих технологий каких-то перспектив.
                                                                                                          +1
                                                                                                          ну, флешплеер всё-таки сдох
                                                                                                            +2
                                                                                                            сдох-не сдох, но Block Plugins пока отключать рано
                                                                                                        +7
                                                                                                        … новым двадцатитысячестраничным стандартом…
                                                                                                    +7
                                                                                                    Что-то я уже не уверен что введение новых сущностей просто чтобы писать меньше строчек себя оправдывает.

                                                                                                    Особенно неоднозначное отношение к string_view — как говорится если раньше было два способа написать функцию работающую со строками, то теперь их три. И каждый из них по-своему плохой.

                                                                                                    Впитывая в себя куски из boost'а стандарт становится такой же беспорядочной помойкой — безумно распухшей коллекцией «прикольных фишечек».
                                                                                                      +9

                                                                                                      string_view это как раз очень хорошо — но чертовски поздно. Как и array_view. Надеюсь, к 20-му году прикрутят. А должны были вкрутить ещё в самом начале, в крайнем случае в 11-й версии. Но не судьба.

                                                                                                        +2

                                                                                                        Ну string_view как раз штука удобная и нужная, да и раньше ей пользоваться можно было, что я успешно и делал. А вот вещи типа "if (init; condition)" тоже настораживают. Может это, конечно, во мне консервативность говорит, но оно кажется далеко не самым частым частным случаем. Для сравнения for по диапазону из C++11 мне очень нравится, да и случай чуть ли не самый частый.

                                                                                                        +9
                                                                                                        Какой кошмар!!! (Я в положительном смысле :). Интересно, а комитет изучал вопрос, сколько людей в состоянии изучить современный С++ с нуля, а не практикуя его постепенно в течении 20 лет?
                                                                                                        Мне кажется, что пора уже заканчивать с этим и нужно садиться за написание книг, где подробно описывать как теперь все это использовать и самое главное, что не использовать из старых практик, пока они сами не забыли как правильно.
                                                                                                          0

                                                                                                          Это, вообщем-то, основная проблема. Сейчас мы можем втянуть студентов в С++ только силой, т.к. добровольно никто на нем писать не будет — сядут за C# или Java, сделают свое приложение, начнут его продавать. А в C++ остались те кто, как я, слишком долго сидел в этой теме и имеет некоторые априорные знания о том как все было 10-15 лет назад, и как проэволюционировало.

                                                                                                            +9

                                                                                                            Потому что стандарт распух до неприличия — а многих действительно важных вещей нет до сих пор. А многих, таких как простого менеджера зависимостей и сборки, не будет никогда.
                                                                                                            Поэтому С++ со временем выдавят. На это уйдёт куча времени, но его место займут другие языки. Что забавно, С, думаю, останется сильно дольше — т.к. он гораздо проще.

                                                                                                              +1

                                                                                                              Слушайте, я вот недавно в Сан Фран ходил на встречу SG14, и там один человек на полном серьезе предлагал встроить С++ package management в язык (!!!). Хотя на дворе 2016 год и идея внешнего описания зависимостей уже проработана и испробована в Cargo, NuGet и так далее. То есть даже в C++ Working Group есть люди которые далеки от понимания того, что творится в мире разработки.

                                                                                                                +2

                                                                                                                Это, простите, капец. По-моему, это PL/1 v2 уже какой-то.
                                                                                                                Хотя, с другой стороны, заставить всех использовать единый формат пакетов и проектов можно только жёстко впилив его в стандарт. Но этого не будет никогда — потому что MS, Google, GCC team будут вечно тянуть одеяло на себя.


                                                                                                                /fanboy mode on
                                                                                                                Хочу только одну вещь. Поддержку в Rust'е импорт C headers из коробки. После этого "два крестика" покатится cо всё нарастающей скоростью.

                                                                                                                  +3
                                                                                                                  Хочу только одну вещь. Поддержку в Rust'е импорт C headers из коробки.

                                                                                                                  Мне кажется, усложнять язык для этого нет нужны, лучше доработать bindgen: https://github.com/crabtw/rust-bindgen#plugin

                                                                                                                    +1

                                                                                                                    Там ЕМНИП самая большая проблема осталась — макро константы. Но не будем здесь разводить оффтоп.

                                                                                                                  +2
                                                                                                                  Когда Степанов выступал в «Яндексе» (видео доступно), он рассказывал про комитет, и говорил, что там очень много людей, которые просто за счёт компании едут посмотреть на Париж и другие места, где проходят заседания комитета. Дословно было сказано: "У них нет знаний, но зато есть мнение.", а работа комитета устроена так, что каждое предложение, нужно изучить и аргументированно утвердить или отказать, т.ч. бюрократия сильно мешает.
                                                                                                                    +1
                                                                                                                    А опытных разрабов почему не посылают? Работать будет некому?
                                                                                                                      0
                                                                                                                      Видимо едут много халявщиков от компаний (с секретаршей), до понимающих людей путёвка не доходит! :)
                                                                                                                +2
                                                                                                                Это, вообщем-то, основная проблема. Сейчас мы можем втянуть студентов в С++ только силой, т.к. добровольно никто на нем писать не будет — сядут за C# или Java, сделают свое приложение, начнут его продавать.

                                                                                                                Ну я вот студент, который работает сейчас С++ программистом. Проблема не в языке скорее, в том, что найти работу для С++ программиста начинающего уровня сейчас во много раз сложнее, чем для тех же С# / Java (при одинаковых, если не больших, уровнях з/п). Вот и желающих стрелять себе в ногу мало.
                                                                                                                  0

                                                                                                                  Для С++ я советую финансовый сектор в крупных городах — Лондон, Нью Йорк, Чикаго.

                                                                                                                    0
                                                                                                                    Вот только попасть в НЙ или Чикаго из России нереально :)
                                                                                                                      +2

                                                                                                                      С чего вы взяли? Попасть куда угодно — реально если у вас есть навыки.

                                                                                                                        0
                                                                                                                        Как, позвольте узнать? На рабочей визе лотерея с конкурсом 20 индусов на место, на «гринке» опять же лотерея с невнятными перспективами. Гарантированного варианта нет. Переводом из Европейского офиса только если, и то не уверен.
                                                                                                                          0
                                                                                                                          По H-1B действительно сложно, подтверждаю. Говорят, есть несколько очень масштабных фирм, которые все квоты под себя почти подчистую выгребают.

                                                                                                                          Можно поехать учиться, по F-1 потом можете пару лет работать, а там, авось, и H-1B выиграете (один мой приятель так и сделал). Можно, действительно, в европейский офис, а потом по L-1, но L-1 вас привязывает к работодателю.
                                                                                                                            0
                                                                                                                            Лично мне виза по учёбе несколько поздновата, но другим информация будет полезна :)
                                                                                                                              0
                                                                                                                              Про учёбу я рассказать не смогу, это действительно мой приятель, а не я сам :)
                                                                                                                            0
                                                                                                                            У индусов квоты на въезд много ниже и выбираются моментом, а в иной год вообще полностью закрывают набор из Индии. В этот момент девелоперам из менее населённых стран получить H-1B становится гораздо легче.
                                                                                                                              0
                                                                                                                              Кстати интересный момент, не слышал о таком раньше, спасибо за подсказку :)
                                                                                                                                +1
                                                                                                                                Стоп, я похоже пал жертвой склероза: квоты по странам — это для гринкарты :( Для рабочей визы есть только две квоты — общая (65000), и для тех, кто закончил какой-нибудь американский университет (20000).

                                                                                                                                Но вообще, если вы найдёте работодателя-спонсора, то шансы достаточно велики, чтобы пробовать.
                                                                                                                        +2
                                                                                                                        С радостью бы уехал туда хоть сейчас, но подозреваю, что работодатели в этих городах не будут заниматься релокейтом кого-то из Украины/России без, условно, 10+ лет опыта в конкретно интересующей их технологии.
                                                                                                                          +1
                                                                                                                          Зависит. Меня в 23 года релокейтнули.
                                                                                                                            0
                                                                                                                            Расскажите?
                                                                                                                              +1
                                                                                                                              Написал в личку. Когда-нибудь оформлю в статью, если не забуду.
                                                                                                                                0
                                                                                                                                Лучше напишите статью… но если никак, то хотя бы в личку напишите, пожалуйста…
                                                                                                                            +1
                                                                                                                            «Ну ты бы хоть лотерейный билет купил»

                                                                                                                            Будут-будут. Куча форумов исписано, поищите. Всякие гуглы-майкрософты-амазоны периодически устраивают глобальный чёс в поисках сотрудников и приезжают сами. Отправьте резюме, сходите на интервью. В первый раз не взяли, повторите через год. Другие компании проводят собеседование по скайпу/телефону. Третьи, хотят решение задач по имейл.

                                                                                                                            Если ваша цель переехать в другую страну, но пока что есть предложения только от, скажем, фейсбука, с которым у вас принципиальные разногласия, то можно перебится год-два и уже на месте найти то, что хочется.
                                                                                                                    0
                                                                                                                    Так а что с ranges?
                                                                                                                      +1
                                                                                                                      Они зависят от концептов. Сначала примут концепты, потом рейнджи. Когда примут концепты, и примут ли их — не известно.
                                                                                                                        +1

                                                                                                                        А как они зависят? На обычных шаблонах, кажется, без проблем делается.
                                                                                                                        Таскать везде begin и end вместо одного range — неудобно.
                                                                                                                        Тот же string view — это же, по сути, range, но почему-то только для строк?

                                                                                                                          0
                                                                                                                          Ranges это не только добавление пары перегруженых методов к алгоритмам. Это еще и очень тесная интеграция с концептами и переписывание большей части снатдартной библиотеки. Так например метод all_of в данный момент выглядит вот так:

                                                                                                                          template<class InputIterator, class Predicate>
                                                                                                                          bool all_of(InputIterator first, InputIterator last, Predicate pred);
                                                                                                                          


                                                                                                                          С Ranges он будет выглядеть вот так:

                                                                                                                          template<InputIterator I, Sentinel<I> S, class Proj = identity,
                                                                                                                              IndirectCallablePredicate<projected<I, Proj>> Pred>
                                                                                                                          bool all_of(I first, S last, Pred pred, Proj proj = Proj{});
                                                                                                                          
                                                                                                                          template<InputRange Rng, class Proj = identity,
                                                                                                                              IndirectCallablePredicate<projected<iterator_t<Rng>, Proj>> Pred>
                                                                                                                          bool all_of(Rng&& rng, Pred pred, Proj proj = Proj{});
                                                                                                                          


                                                                                                                          Оценить масштаб изменений можно почитав proposal: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4569.pdf
                                                                                                                            0

                                                                                                                            А это как-то мешает сейчас ввести ranges как простой шаблон с begin и end, а потом (если это потом настанет) уже расширить его концептами?
                                                                                                                            Переделок будет даже меньше, чем делают сейчас, например, с параллельными алгоритмами.

                                                                                                                              0
                                                                                                                              Одна из особенностей Range — begin и end могут быть разными типами (в примере выше это можно увидеть). Без этой возможности реализация значительно усложняется. А при её наличии ломается совместимость с предыдущими версиями стандартной библиотеки.
                                                                                                                      +18
                                                                                                                      Я большой фанат C++, но когда я читаю очередной черновик стандарта, мне всегда вспоминается этот комикс:
                                                                                                                      комикс про 4096 процессоров

                                                                                                                      Да, есть хорошие и удобные фичи. Но дофига нужного до сих пор нет!

                                                                                                                      Навскидку:
                                                                                                                      1) нормальные, черт возьми, строки!
                                                                                                                      2) модули
                                                                                                                      3) полиморфные лямбды
                                                                                                                      4) xml, json и прочая сериализация/десериализация из коробки
                                                                                                                      5) в мире существует сеть, и пора бы уже о ней узнать!
                                                                                                                      6) ну и еще кучу всего, ночью уже сложно вспоминать…
                                                                                                                        +3
                                                                                                                        Что вы называете полиморфными лямбдами? А что — нормальными строками?

                                                                                                                        А вообще, а вообще… Лучше бы хорошую compile-time type information, чтобы можно было адекватно AST манипулировать, писать автоматический вывод той же сериализации хоть в json, хоть куда хочешь, и так далее.
                                                                                                                      • UFO just landed and posted this here
                                                                                                                          +4
                                                                                                                          А в каком контексте текущие лямбды не полиморфны?
                                                                                                                            0
                                                                                                                            1) работа со строками это грусть, но это скорее претензии к STL, а не к языку.
                                                                                                                            2) ну все ждут и все хотят, но это такая глобальная тема, что комитет не хочет сделать какашку, от которой следующие 30-50 лет люди будут страдать.
                                                                                                                            3) а сейчас что не так
                                                                                                                            4) дайте рефлексию, и все это будет не нужно. А черновиков по рефлексии несколько уже есть.
                                                                                                                            5) вот тут просто +100500. Хотя бы ip-сокеты/listener-ы стандартизировали.
                                                                                                                              0
                                                                                                                              Да, рефлексии очень не хватает
                                                                                                                                0

                                                                                                                                5) тут можно много копий поломать. К примеру, проакторный Asio я бы не сильно хотел видеть в качестве реализации сети в стандарте. Плюс, говоря о сети, нужно думать и о эффективной работы, неблокирующем режиме и мультиплексировании… А вот тут некая система Windows выделяется своим IOCP (без спора — что эффективнее)...

                                                                                                                                  +2
                                                                                                                                  Работа над сетью идёт, на данный момент самым жизнеспособным предложением является предложение на основе ASIO, но правиьно переработанное http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4575.pdf.

                                                                                                                                  Очень много интересов сошлось на этом proposal. Все хотят сеть, но у всех разные желания: производительность, отзывчивость, простота, сопрограммы, единый интерфес с многопоточностью/stl, расширяемость и т.д.

                                                                                                                                  Всей душой болею за это предложение и при том не я один. Должно получиться очень красиво и правильно, не не известно к какому году.
                                                                                                                                    0
                                                                                                                                    Спасибо большое за ссылку, очень интересно!
                                                                                                                                  +2
                                                                                                                                  Это, конечно, интересные фичи. Только зачем они в стандарте?
                                                                                                                                    +3
                                                                                                                                    А где еще модулям и рефлексии быть?
                                                                                                                                      –3
                                                                                                                                      Без модулей и так неплохо. А кому нужна рефлексия, тот знает, где скачать Java.