Итоги 2015-го года для C++

http://www.bfilipek.com/2015/12/c-status-at-end-of-2015.html
  • Перевод
  • Tutorial
Возможно, я скажу банальную вещь, но прошедший год был хорошим годом для С++!

Просто факты:
  • Вышла Visual Studio 2015 с отличной поддержкой возможностей С++14/17 и даже нескольких экспериментальных вещей
  • Вышел долгожданный GCC 5.0
  • С++ набрал серьёзную популярность. Где-то с июля — третье место в Tiobe Ranking
  • На конференции CppCon 2015 было сделано несколько важных анонсов


А теперь об этом и другом немного подробнее


Статус поддержки С++11


Компиляторы Clang, GCC и Intel Compiler имеют полную поддержку C++11.
В Visual Studio не хватает двух вещей: Expression SFINAE — N2634 и C99 preprocessor — N1653

Статус поддержки С++14


Clang и GCC полностью поддерживают C++14. А в общем дела обстоят так:


Изменения с прошлого года отмечены звёздочкой (*)

В Visual Studio 2015 компилятор С++ стал заметно ближе к полному соответствию стандарту, были реализованы Sized deallocation, атрибут [[deprecated]] и поддержка одинарной кавычки в качестве разделителя разрядов в числах.

Хороший прогресс показал и компилятор Intel — они добавили поддержку обобщённых лямбда-функций, инициализацию членов класса (включая агрегатную), плюс всё те же аттрибут [[deprecated]] и поддержку одинарной кавычки в качестве разделителя разрядов в числах.

Статус поддержки С++17


Очевидно, большинство из нас ждёт этого грандиозного события, которое должно уже вот-вот произойти: стандартизации С++17! Да, компиляторам нужно ещё поработать над поддержкой С++11/14, но большинство фич уже реализованы или находятся на последних этапах реализации. Команды разработчиков всех основных компиляторов уже активно экспериментируют с некоторыми новыми фичами будущего стандарта С++17.

Но что включает в себя С++17?
Для полного понимания предмета лучше всего будет прочитать "Мысли по поводу С++17" от Страуструпа. Он выделил три основных приоритета:
  1. Улучшить поддержку масштабирования для больших проектов
  2. Добавить поддержку высокоуровневого параллелизма
  3. Сделать ядро языка проще, улучшить STL


Кроме того, С++17 запланирован быть мажорным релизом языка, т.е. кроме мелких апдейтов мы получим и нечто более крупное:

  • Модули — n4465, n4466
  • Контракты — n4415
  • ASIO для работы с сетью — n4478
  • SIMD-векторизация — n4454
  • Улучшенные futures — n3857, n3865
  • Корутины — N4402, n4398
  • Транзакционная память — n4302
  • Параллельные алгоритмы — n4409
  • Концепты — n3701, n4361
  • Концепты в стандартной библиотеке — n4263
  • Ranges — n4128, n4382
  • Унифицированный синтаксис вызова — n4474
  • Оператор точка — n4477
  • array_view и string_view — n4480
  • Массивы в стеке — n4294
  • optional — n4480 — optional
  • Свертка выражений — N4295
  • __has_include в условиях препроцессора — P0061R1
  • Файловая система — n4099
  • Множество более мелких изменений


Вот отличный обзор всех потенциальных возможностей С++17.
Те фичи, которые не успеют войти в С++17, войдут в следующий стандарт С++20, который планируется как минорный. С++20 отполирует С++17, как С++14 отполировал С++11.

Core Guidelines


На конференции CppCon в ключевой презентации Бьёрн Страуструп сделал важный анонс: Core Guidelines!

Полная версия гайдлайнов находится на GitHub, вот выдержка из вступления:

«С++ Core Guidelines являются результатом совместной работы группы авторов под руководством Бьёрна Страуструпа, как, собственно, и сам язык С++. В разработку этих рекомендаций вложено много человеко-лет труда людей из множества организаций. Дизайн данных гайдлайнов предполагает их общее применение и широкое распространение, что однако, не исключает ваше право скопировать и изменить их под нужды вашей организации.

Целью разработки данных инструкций является помочь людям использовать современный С++ эффективно. Под „современным С++“ мы подразумеваем С++11 и С++14 (а вскоре и С++17). Мы поможем представить вам как ваш код, который вы начнёте писать сегодня, будет выглядеть через 5 (или 10) лет.»

Поскольку язык становится богаче, современнеее (но в то же время и проще) будет очень полезно иметь такой справочник. Некоторые хорошо известные правила заменены новыми подходами — например, RAII. Переход на них не так прост, особенно, если вы поддерживаете старую кодовую базу и хотите добавить что-нибудь современное в свой код. Core Guidelines разрабатываются коллективно, а значит, должны стать достаточно практичным инструментом.

Речь Бьёрна Страуструпа:


Дополнение к ней от Херба Саттера:


Стандартизация С++


В прошлом году прошли две встречи комитета по стандартизации С++: Кона в Октябре и Ленекса в Апреле.

Пару слов о весенней встрече:


И об осенней:


Намечены следующие встречи комитета по стандартизации в 2016-ом году: во Флориде в феврале и в Финляндии в июне (на этой встрече планируется голосование за стандарт С++17).

Новости мира компиляторов


Visual Studio



GCC



Clang



Intel compiler



Конференции


В прошлом году прошло две важных конференции: CppCon и MettingCpp

CppCon



MeetingCpp



Первый доклад:


и второй:


Заключение


Как мы видим, комитет по стандартизации С++ прилагает серьёзные усилия по работе над стандартом С++17. К концу года мы можем рассчитывать на принятие черновика этого стандарта. Разработчики чувствуют новую атмосферу перемен и это отражается в рейтингах популярности языка (в Tiobe Rank С++ набрал 8%). Термин «ренессанс С++» уже не миф…

Что ещё лучше — у нас есть множество экспериментальных фич в компиляторах. Мы уже можем экспериментировать с модулями, концептами, корутинами… Это, конечно, пока не безопасно и не может быть применено в продакшн-коде, но в плане обучения и тестирования очень интересно. Кроме того, это даёт возможность получить некоторый фидбек, который может повлиять на финальную спецификацию всех этих вещей.

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

Все компиляторы поддерживают С++11/14 на достаточно хорошем уровне, так что больше нет оправданий не переходить на использование этих стандартов. С помощью Core Guidelines данная задача становится ещё проще.

Грустные новости
Буквально пару часов назад Скотт Майерс опубликовал статью-прощание с миром С++. Обсуждение на reddit

А что вы думаете?
  • Что вам запомнилось из события около С++ в 2015-ом году?
  • Что я пропустил?


Ну и опросничек.
Какие фичи вы бы хотели непременно увидеть в С++17

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

Инфопульс Украина 166,77
Creating Value, Delivering Excellence
Поделиться публикацией
Комментарии 90
  • –5
    «C++ набрал серьёзную популярность в 2015» звучит неправдоподобно. Даже если он действительно таки набрал, а не растерял популярность, это единицы процентов по отношению к той популярности, которую он набрал за предыдущие десятилетия.

    Tiobe это мусорный рейтинг, в котором Go был на 49 месте (а сейчас выпал из 50, ха-ха-ха)
    • +5
      TIOBE — вполне себе рейтинг. Разве есть что-то лучше?

      Просто погрешность, с которой происходят измерения, довольно велика, и поэтому дальше первой десятки можно не смотреть.
      • +2
        Он составляется на основе поисковых запросов, если меня память не подводит. Более-менее показывает, сколько НОВИЧКОВ начинает пользоваться языком (не очень могу представить, чтобы я начал гуглить «C++ how to remove object from vector», у меня сомнения что запросы вроде «std vector emplace_back» попадут в статистику по языку.

        «разве есть что лучше» — ну «чуть лучше» я бы назвал статистику по резюме/вакансиям с упоминанием этого языка.
        • –3
          «Композитные» рейтинги популярности не работают, имхо. Надо смотреть более конкретные метрики. Кол-во вакансий на hh. Кол-во вопросов (или, например, только новых вопросов) на stackoverflow. Кол-во проектов на github. И т. д.

          По Tiobe С в 6-7 раз популярнее JavaScript. При всей моей нелюбви к последнему, это не погрешность, это бред.
        • +1
          Как составить рейтинг рейтингов?

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

        • 0
          Спасибо за обзор.
          Все-таки думаю что у С++ очень неплохие перспективы в свете падения темпов роста производительности процессоров.
          • +4
            Поскольку язык становится богаче, современнеее (но в то же время и проще)

            Не заметил упрощения…
            • +11
              Ну сравните проход по std::map раньше и теперь.
              Было:

              typedef std::map<std::string, std::map<std::string, std::string>>::iterator it_type;
              for(it_type iterator = myMap.begin(); iterator != myMap.end(); iterator++) 
              {
                  // do something
              }
              


              стало:

              for (auto& k : myMap) 
              {
                  // do something
              }
              


              Заметили упрощения?
              • +5
                Согласен, писать стало проще, а вот понимать теперь нужно уметь больше, старый способ же не исчез из языка.
                Не важно сколько фич ты используешь когда пишешь свой код, в реальном мире понимать чужой все равно необходимо. В этом плане, имхо, сложнее всего Scala, но C++ не сильно отстает.
                • –8
                  С++ — довольно прост для понимания для любого, кто знает этот язык. Почему-то расхоже мнение, что в нём большое количество сложных конструкций, но это не так. C++ сложно читать только если вы не знаете C++, а это характерно для многих языков.
                  • +8
                    А кто его знает?
                    • +1
                      Рискну осторожно предположить, что Бьерни знает…
                      • +6
                        Ну… он давал оценку своим знаниям, примерно, как 7 из 10. Честно скажу, не помню точно где я это видел, так что прошу поправить если сильно ошибся.
                        • 0
                          Нет, я смутно-смутно что-то такое помню, поэтому и сказал «осторожно».
                      • 0
                        Александреску наверное…
                      • –3
                        Господа минусующие, можно пример кода на С++ в котором сложно разобраться? Не холивара ради, просто хочется понять — может быть, я просто слишком давно пишу на плюсах и у меня действительно «глаз замылился»?
                        • +4
                          Я код свой периодически показываю не совсем прям чтоб опытным в C++ людям, и вещи вроде такого или такого или такого им не очень.

                          При этом я фанат плюсов, да.
                          • 0
                            Просто случайная строчка кода из самой популярной библиотеки.
                            Bind, далеко не самая страшная вещь в бусте.

                            И да, это сложно, про простые вещи не пишут статей в духе «Давайте рассмотрим как заимплеменчена эта концепция через синтаксисе с++».
                            • 0
                              Причём здесь язык-то? Нафигачить однобуквенных аргументов можно в любом языке. Давайте быть объективными, такие строчки бывают в любых языках программирования. Внутри библиотек на джаве и питоне ещё и не такое встречается, не говоря уже про скалу. Однако, эти языки почему-то не считаются сложными. Что я упускаю?

                              Синтаксис С++ громоздкий, с этим никто не спорит, но он не сложнее для понимания большинства других.
                              • 0
                                Сложными для чтения, конечно же
                                • 0
                                  К слову о Scala, вспомнилась библиотека, с которой недавно пришлось иметь дело: биндинги к gnuplot для Haskell.

                                  Совершенно недокументированная, каждый тайпкласс называется C, каждый тип данных называется T, различаются по имени модуля, их экспортирующего.
                                  • 0
                                    Да при чем здесь однобуквенные названия? Сложность в реализации!
                              • +2
                                С++ — довольно прост для понимания для любого, кто знает этот язык.

                                Это фраза ни о чем. Человек говорит, что чем больше конструкций в языке (втч упрощающих жизнь), тем язык сложнее, потому что надо знать уже n+1 конструкцию для чтения кода. Вы парируете «кто знает язык, тот знает язык».
                                Например — я очень редко пишу что-то на С++, при этом конструкция
                                typedef std::map<std::string, std::map<std::string, std::string>>::iterator it_type;
                                for(it_type iterator = myMap.begin(); iterator != myMap.end(); iterator++) 
                                {
                                    // do something
                                }
                                

                                нереально громоздка, но понятна любому, кто знает что-то о шаблонах (базовом элементе языка, которому 100 лет в обед).

                                Конструкция
                                for(auto it_type iterator = myMap.begin(); iterator != myMap.end(); iterator++) 
                                {
                                    // do something
                                }
                                

                                И проста и понятна, в том числе для тех, у кого ++ — не основной язык, потому что механика спецификатора auto прозрачна.
                                А вот запись
                                for (auto& k : myMap) 
                                {
                                    // do something
                                }
                                

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

                                Проще для написания.
                                Сложнее для понимания.
                                • 0
                                  Я согласен с вами, но ведь аналогичные конструкции есть и в других языках, например в джаве, которой никто не предъявляет сложность. Моя фраза относилась к части
                                  В этом плане, имхо, сложнее всего Scala, но C++ не сильно отстает.
                                  С тем, что язык становится сложнее спорить тяжело.
                                  • 0
                                    Даже для понимания проще, если знать, что такое auto и как выводятся типы у шаблонов (а в C++ это знать всё равно надо). Просто потому, что не нужно визуально парсить все эти гроздья begin и end.

                                    Кроме того, range-based for loop сразу чётко даёт понять намерение кода чуть лучше, чем старый-добрый for loop. Понятно, что на каждой итерации мы всегда переходим к следующему элементу контейнера. Понятно, что мы не инвалидируем итераторы (например, не удаляем элементы из вектора или не добавляем новые). Ну и ещё что-нибудь понятно.
                                    • 0
                                      Даже для понимания проще, если знать, что такое auto и как выводятся типы у шаблонов (а в C++ это знать всё равно надо).

                                      И об этом — второй предложенный мною вариант, а не 3й.

                                      Кроме того, range-based for loop сразу чётко даёт понять намерение кода чуть лучше, чем старый-добрый for loop

                                      Вы не поняли основную мысль.
                                      Разговор шел о том, что чем больше разнообразие конструкций, тем язык сложнее. Только и всего. Шаблонам — 100 лет в обед, их все знают. auto интуитивно понятен, именно поэтому второй варинат читается легко — это комбинация интуитивно понятного и старого, всем известного. А вот range синтаксис уже китайская грамота. При том, что это удобная вещь.

                                      • +1
                                        Ну так если б вы написали «сложнее для понимания тем, кто привык к старому C++, а на новом никогда не писал, и заодно никогда не трогал Qt с Q_FOREACH или Boost с BOOST_FOREACH», то с вами сложно было бы не согласиться.
                                        • 0
                                          Человек изначально написал «Согласен, писать стало проще, а вот понимать теперь нужно уметь больше, старый способ же не исчез из языка», так что контекст очевиден.
                          • 0
                            Вообще если смотреть рейтиги TIOBE видно что рейтинг языка низок как никогда (хотя и правда сейчас на 3 месте)

                            www.tiobe.com/index.php/content/paperinfo/tpci/C__.html

                            А вообще уже 2016 год, а я знаю кучу компаний (наверное большинство) которые даже С++11 не используют (и значит им все это не надо — что кстати тоже не плохо — кого то устраивает то что есть)

                            А те кто следят за новинками языка и кому это действительно важно — те будут использовать, например Rust. Конечно остаются проблемы поддержки legacy code, но как раз для этого не так уж и важен новый стандарт.
                            • +4
                              Я пытался предложить улучшения в области метапрограммирования — разрешить передавать в шаблоны не только типы и целочисленные константы, но и любые другие compile-time конструкции (включая float-константы, строки и даже произвольные корректные фрагменты кода)
                              К сожалению, народ на isocpp.org не поддержал.
                              • 0
                                А можно ваш proposal глянуть почитать? Особенно интересна motivation часть, конечно.
                                • 0
                                  Лично я вижу в предложении NeoCode, как минимум, унификацию ибо текущие ограничения в большинстве своём не понятны и избыточны, а также явную возможность избавления от макросов для генерации кода много где, отдав эту функциональность шаблонам.
                                  • +1
                                    Я в основном и имел в виду унификацию. Что касается мотивации, то я особо не расписывал, т.к. реальные примеры где это нужно достаточно сложные и их сложно объяснить вне контекста реальных проектов. Но на этом и рефлексию можно сделать, и кодогенерацию, и много чего еще.
                                    • 0
                                      Рефлексию я не представляю, как можно через это сделать, интересно стало, можете с потолка пример как это может работать?
                                      • 0
                                        Я не NeoCode, но смею предположить что-то в духе
                                        class Foo : public DeclareMembers<
                                                void SomeFunction (),
                                                std::string SomeOtherFunction (const std::string&) const
                                            >
                                        {
                                        // ...
                                        };
                                        

                                        которое внутри развернётся в объявления функций SomeFunction, SomeOtherFunction, и регистрацию их в каком-то движке рефлексии.
                                • 0
                                  О, а поделитесь своим опытом, пожалуйста!

                                  Я уже джва год хочу написать пропозал, чтобы за soft errors при выводе/подстановке шаблонных аргументов принимались не только ошибки в immediate context, но и в инстанциациях всего, что участвует в immediate context, да ленюсь.

                                  Мотивирующе-поясняющий пример.

                                  Заодно можно делать всякие прикольные вещи вроде компил-тайм-тестов, что некоторый код не компилируется. Полезно при разработке всякой шаблонной наркомании.
                                • –9
                                  Осталось добавить Garbage Collector и будет ещё одна Java/.NET вирт машина.
                                  Кстати .NET умеет собирать в нативный код (уже), т.е. работает как приложение написанное на C++.
                                  https://msdn.microsoft.com/en-us/vstudio/dotnetnative.aspx
                                  • +9
                                    Я либо вас не понял, либо вы неправы просто-таки фундаментально.
                                    • 0
                                      Я имел в виду, что в C++ появляются постепенно сахар, который уже давно есть в C# и возможно придут к Garbage Collector со временем.
                                      А тем временем C#/.NET идет на встречу C++ — ускоряя загрузку приложения, уменьшая потребление памяти.
                                      • 0
                                        Мне представляется, что вероятность появления GC в С++ крайне мала, а вот опциональный ARC как в Objective-C может когда-нибудь и будет.
                                        • +2
                                          Я не знаком с Objective-C но разве std::shared_ptr<T> не решает ту же задачу?
                                          • 0
                                            Задача та же, но решает принципиально хуже в первую очередь потому, что писать каждый раз конструкцию уменьшающую читабельность как-то вообще не камильфо. Тут дело в другом, это решение более гибкое — если проекту нужна максимальная скорость работы, то есть возможность вообще отказаться от использования умных указателей, или применять их ограничено. Если скорость не так критична, и умные указатели используются повсеместно — то глобально включенный ARC будет эквивалентен и избавит лишних движений.

                                            std::shared_ptr<SomeType> someName = std::make_shared<SomeType>(constructor, parameters, here);
                                            
                                            vs
                                            
                                            SomeType *someName = new SomeType(constructor, parameters, here);
                                            

                                            • 0
                                              SomeType *someName = new SomeType(constructor, parameters, here);
                                              auto someName = std::make_shared(constructor, parameters, here);
                                              разница в 10 символов или 13%.
                                              Для максимальной скорости выделения памяти обычно пулы используют, либо что-то вроде placement new.
                                              • 0
                                                • Во-первых, где в этой строчке тип указывается хоть один раз? Мне кажется что-то пропущено.
                                                • Во-вторых, auto не везде разумно/возможно вставлять, в объявлении полей класса или параметров методов, их возвращаемого значения все равно нужно прописывать типы явно, так что читабельность все равно падает по сравнению с голыми указателями, число символов возрастает.
                                                • В третьих несколько вариантов написания одного и того же явно избыточны, каждый будет писать как придется, опять вспоминаем про увеличивающуюся фрагментацию.
                                                • +1
                                                  Насчёт конструкции, уменьшающей читабельность — спорно. Многие могут вам сказать, что явное указание, что переменная является умным указателем, повышает читабельность, ведь программисту не надо гадать, умные указатели используются в этом конкретном проекте или нет.
                                                  Насчёт пункта 3 — с этим приходится мириться, потому как ломать обратную совместимость никто не будет.
                                                  • 0
                                                    Если мы все еще говорим об ARC, то это определяется глобально в настойках проекта, и все указатели становятся умными, гадать не нужно.
                                                    • +1
                                                      Да о том и речь, что просто посмотрев на кусочек кода/файл (например, нагуглив) нельзя точно сказать, включён он или нет.
                                                  • 0
                                                    во-первых, я не посмотрел предпросмотр, и хабрапарсер зохавал шаблон. Разница в 13% в пользу new, естественно.
                                                    про авто — согласен, его только в таких очевидных примерах, где тип явно виден, удобно использовать (или для лямбд).
                                                    3) — тут не поспоришь.
                                                • –1
                                                  Дополню mapron поскольку использовать new и delete не безопасно, впрочем как и сырые указатели, а с C++14 это окончательно пофикшено и в общем случае следует использовать unique_ptr вместе с make_unique так что разница в написании вообще нулевая.

                                                  P.S. на всякий случай напоминаю всем разработчикам на C++, что unique_ptr+make_unique фактически является синтаксическим сахаром и не привносит дополнительных накладных расходов при сравнении с сырыми указателями и использованием new+delete, однако его использование гораздо более безопасно из-за особенностей генерируемого кода, впрочем как и из-за отсутствия необходимости явного вызова delete, в котором помимо явной утечки в случае exception перед ним можно ещё ошибиться из-за [] в случае массива (неважно при каких условиях, факт в том, что можно). Ошибку же с использованием new+delete можно отловить только при анализе утечек памяти при завершении работы приложения в рантайме либо грубые ошибки (массив — единичный элемент в случае delete) некоторыми статическими анализаторами.

                                                  P.P.S. я понимаю о чём вы говорите и что можно сделать синтаксис проще, но для этого, учитывая концепцию C++ надо будет однозначно вводить специальную директиву, отключающую обратную совместимость и это касается не только new, но и многого другого из «наследия прошлого». Наверняка после введения модулей такую директиву сделают, чтобы в пределах модуля использовать канонический C++ с обратной совместимостью, а вне его пределов уже современную на тот момент версию языка. Но это пока только мысли на будущее ибо требует очень большой работы от разработчиков компиляторов, а пока уж как есть ибо и так изменений огромное количество и для авторов компиляторов и для разработчиков на языке.
                                                  • 0
                                                    поскольку использовать new и delete не безопасно, впрочем как и сырые указатели
                                                    Ну вы нашли, чем плюсовика напугать:
                                                    «Си — инструмент, острый, как бритва: с его помощью можно создать и элегантную программу, и кровавое месиво» Брайан Керниган
                                                    Если серьезно, то нулевая разница только по сравнению с shared_ptr, пример же приведен для сравнения с ARC, и unique_ptr тут картину не улучшает. Но в целом замечание ценное, спасибо.
                                                    • 0
                                                      Ну вы нашли, чем плюсовика напугать

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

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

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

                                                      P.P.S. у меня ещё просто профориентация на проекты, которые должны очень долго работать и быть максимально надёжны, так что некоторая паранойя в этой области тоже есть, не скрою :) Вообще мне для заверения треда уж очень хочется пригласить к обсуждению Andrey2008 ибо он как один из разработчиков хорошего (по моему опыту) статического анализатора, наверняка, может ткнуть в годные примеры, где в известных и используемых многими проектах использование new/delete, включая ошибки с оператором [], да ещё и голое их использование без обвёртки без соблюдения принципа RAII приводило к утечкам, порчи памяти и другим «радостям».
                                                      • 0
                                                        Да, таких ошибок много. Однако у меня нет какого-то конкретного мнения, как сделать мир лучше.

                                                        Кстати, можно напортачить c [] не только при использовании голых new/deletе, но и применяя умные указатели.
                                                        • 0
                                                          Да, вот и я не знаю как побороть проблему на корню. С auto_ptr всё уже давно понятно, благо он deprecated с C++11, а с C++17 вообще будет удалён.
                                                          • +1
                                                            `auto_ptr` не умный, а так себе указатель.
                                                      • 0
                                                        впрочем как и сырые указатели

                                                        Сырые указатели вполне себе нормальны и представляют семантику «передать в функцию указатель на объект, не передавая владение».
                                                        unique_ptr — передаёт владение, и вызывающий код его теряет.
                                                        shared_ptr — разделяет владение, что не всегда корректно и не всегда является подразумевавшимся намерением.
                                                        • 0
                                                          В функции unique_ptr можно ведь и ссылкой передавать. Для shared_ptr есть ещё weak_ptr без передачи владения.

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

                                                          Пожалуй самое главное замечание на счёт умных и сырых указателей: не стоит мешать их вместе для одного объекта ибо этим можно создать себе дополнительные и особенно экзотические проблемы.
                                                          • +1
                                                            В функции unique_ptr можно ведь и ссылкой передавать. Для shared_ptr есть ещё weak_ptr без передачи владения.

                                                            Это делает ваши функции менее универсальными. Если вы написали, что функция принимает unique_ptr по ссылке, то указатель на объект на стеке, например, вы уже не передадите. Если вы написали, что функция принимает weak_ptr, то указатель на объект на стеке вы уже не передадите (без особых костылей). Зачем такие ограничения, если всё, что нужно функции — указатель на объект, и её требование — чтобы объект был жив всё время работы функции, и не более, а об особенностях жизни объекта вне неё она не заботится и не должна?

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

                                                            ИМХО единственное, что в контексте памяти опасно — явные new и delete. Вот их надо стараться всяко исключать, да.
                                                            • 0
                                                              Да, вы правы. С меньшей универсальностью полностью согласен. Также и с тем, что самое опасное это явные new и delete.
                                                      • 0
                                                        При помощи лёгкого макроса и маленькой шаблонной функции можно превратить это
                                                        std::shared_ptr<SomeType> someName = std::make_shared<SomeType>(constructor, parameters, here);
                                                        
                                                        в это
                                                        
                                                        auto someName = share new SomeType(constructor, parameters, here);
                                                        
                                              • 0
                                                Кстати .NET умеет собирать в нативный код (уже)

                                                Подобные попытки предпринимались неоднократно и многими. Особенно на ранних стадиях развития виртуальных сред исполнения. Вот только один пример для Java среды: https://gcc.gnu.org/java/
                                                Однако приоритет развития был всё-таки отдан «компиляции на лету» (англ. Just-in-time (JIT) compilation).
                                                • 0
                                                  Это не попытка, это готовый продукт. Использовать или нет решайте сами.
                                                • 0
                                                  Да нy нету? C++/CLI для любителей GC.
                                                  • +1
                                                    Там для GC свой тип ссылок и указателей и свой оператор new. managed c++ это редкий уродец с каким то зашкаливающим количеством возможных ссылок на обьекты, сделанный как мне видится, исключительно для написания производительных биндингов в .Net с сабжа и сишечки.

                                                    А, да, там ещё два типа шаблонов, с интересными правилами взаимопременения :)

                                                    Вообщем использовать эту штуку для чего то кроме клея, не приведи ни одному любителю GC как говорится.
                                                • +16
                                                  Боюсь показаться ретроградом в треде про С++17, но господа, не слишком ли много мы получили? Если раньше разговоры про то, что никто не знает С++ полностью были шутками, то теперь это реальная ситуация. Других языков, которые бы так быстро и решительно насыщали фичами я не знаю. В итоге мы оказываемся в ситуации, когда каждый знает и/или использует какое-то свое подмножество, из-за чего язык перестает быть универсальным, разбираться в чужом коде становится гораздо сложнее. И это я еще молчу о злоупотреблении фичами из серии «потому что могу» и «эту я еще не пробовал».
                                                  • –4
                                                    Не думаю. Новые стандарты сейчас вообще мало где используют, а как только станут использовать все сразу во всём разберутся (из тех кто реально пишет на плюсах). Там не так уж много нововведений и они совсем не сложные. А насчёт использования подмножества языка — сейчас картина точно такая же, к сожалению.
                                                    • +1
                                                      move-семантика и всё с ней связанное, как показывает практика, оказывается сложным для восприятия.

                                                      И это я ещё не говорил о наконец-то появившейся многопоточности в стандарте, со всеми вариантами sequential consistency, например.
                                                    • +5
                                                      Проблема в том что C++ спал летаргическим сном с 1998 года до C++2011, в то время как остальные языки постоянно насыщялись удобными фичами. Поэтому теперь приходится наверстывать.
                                                      • 0
                                                        И появились вещи типа Qt (где написали свои библиотеки для всего и оно теперь как-то должно существовать параллельно с этими С++1Х, а Qt используют многие)
                                                        • 0
                                                          И при этом сосуществует оно местами из рук вон плохо. QtConcurrent::mapped в 2016 году не умеет выводить тип возвращаемого значения из лямбды, приходится оборачивать в std::function, например.
                                                          • 0
                                                            Идеального нет, но в целом для работы с Qt требуется очень небольшое и прозрачное подмножество языка без магии и неоднозначностей, сигналы-слоты опускают порог вхождения даже в многопоточное программирование, из-за чего С++03 подтягивается до уровня современного языка. Это я не говорю о средствах работы с сетью, файловой системой, и т.д. что в официальном стандарте только в планах.
                                                            • 0
                                                              сигналы-слоты опускают порог вхождения даже в многопоточное программирование

                                                              Опыт сидения в паре XMPP-конференций и наблюдения за вопросами показывает, что не очень.

                                                              Вот future'ы действительно и опускают порог, и упрощают, и позволяют совершать меньше ошибок, и вообще композабельны и типобезопасны.
                                                      • +1
                                                        то теперь это реальная ситуация

                                                        Да, это уж точно — я преимущественно на C# специализируюсь, и поддерживать знание C++ "в фоне" становится все сложнее и сложнее. Благо моя сфера интересов, связанная с C++, в основном Qt\QML касается, а там более или менее свои законы и устоявшиеся идеологии.
                                                        • 0
                                                          Других языков, которые бы так быстро и решительно насыщали фичами я не знаю.

                                                          C# регулярно обрастает ими прямо-таки с космической скоростью.
                                                          • –2
                                                            Это что были времена, когда в конструкторе можно было выделять память под обьект.

                                                            Жаль что убрали.
                                                            • +1
                                                              Ну так можно перегрузить оператор new внутри класса, и так же выделять память.
                                                          • +3
                                                            Придётся ждать C++: The Good Parts
                                                          • +3
                                                            А compile-time интроспекцию так и не сделали. Придется по-старинке лютым копипастом сериализацию/десериализацию делать.
                                                            • +1
                                                              Даа уж, у меня в подобных особо тяжёлых случаях частенько вообще кодогенерация на макросах #жизнь-боооль.

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

                                                              Когда активно участвовал в проекте FlylinkDC++ то масштабно занимался рефакторингом, в т.ч. гуйной части и там для унификации менюшек и много чего ещё это было нужно, даже вопрос на тостере тогда задал, благо что конкретно в этом случае у Visual Studio оказался специальная конструкция __if_exists благодаря которой в этом случае удалось всё унифицировать «малой кровью».
                                                              • 0
                                                                Для вашей задачи можно сделать что-то вроде

                                                                eval_if(b,
                                                                  [&]() { t->doA(); },
                                                                  [&]() { t->doB(); }
                                                                );

                                                                где b — constexpr boolean выражение
                                                            • 0
                                                              Кстати, у меня такое чувство что предлагаемый «оператор точка» это что-то очень близкое к «свойствам» (properties), которые есть во многих языках. Только более общее: если свойства определяют геттеры и сеттеры для полей класса, то «точка» — геттер и сеттер (одновременно? или можно развести их через const?) для всего объекта класса сразу.
                                                              • 0
                                                                плюс ещё проще писать паттерн прокси
                                                              • +1
                                                                Таки не «корутины», а сопрограммы. :) Термин прижился в русском языке много лет назад. :)
                                                                • 0
                                                                  Еще было бы интересно иметь в языке возможность присваивать классам и функциям произвольные атрибуты, чтобы они наследовались порожденными классами и вызываемыми функциями), и задавать правила соответствия атрибутов объектов класса и работающих с ними функций.

                                                                  Таким образом можно было бы весьма элегантно реализовать обнаружение во время компиляции дедлоков, рискованных операций с объектами, нарушение уровней приоритета в ядре ОС и т.п.
                                                                  • 0
                                                                    функциям произвольные атрибуты, чтобы они наследовались порожденными классами и вызываемыми функциями), и задавать правила соответствия атрибутов объектов класса и работающих с ними функций.

                                                                    Например, как вы это видите?
                                                                    • 0
                                                                      В простейшем случае — примерно так:

                                                                      // Функция, вызываемая на известном уровне приоритета

                                                                      F1 (...) _attrval (Level = 2) {… }

                                                                      // Функция, вызов которой допустим только на определенных уровнях приоритета

                                                                      F2 (...) _attrcond (Level <= 1) {… }

                                                                      Значение атрибута Level, заданное для F1, распространяется на все функции, явно вызываемые из нее. Если на этом пути вдруг встретится вызов F2 — у компилятора будет возможность выдать предупреждение, и не потребуется писать тесты для всех возможных путей вызова F2.

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

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

                                                                      Смысл в этом примерно тот же, что и у константных объектов/методов, только в дополнение к константности вводятся дополнительные атрибуты объекта/функции.
                                                                  • 0
                                                                    Блин, как же я мечтаю о том, чтобы C++ с каждым стандартом всё больше и больше приближался к D, пока в один благословенный день оригинальный код D вдруг не стал собираться C++ компиляторами.
                                                                    • 0
                                                                      Как раз сейчас происходит мощная передача концепций обратно — из D, где они были опробованы, в C++-17. Навскидку — модули, ранги (ranges) и много другого, в материалах CppCon-2015 очень много таких примеров.
                                                                      Полного слияния однако совершенно точно не будет, и это хорошо, зато появятся мощные инструменты для экспорта кода, перекрестному использованию библиотек, и т.д.
                                                                      Предсказываю появления вместо диады C/C++ мощной триады C/C++/D и приветствую ее приход.
                                                                      • 0
                                                                        Как мне кажется, главная проблема D в том, что у него, в отличии от C++ нет ниши.
                                                                      • 0
                                                                        ошибся веткой

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

                                                                        Самое читаемое