Заседания, как обычно, занимали целый день + решено было сократить обеденный перерыв на полчаса, чтобы успеть побольше поработать над C++17.
Несмотря на то, что основное время было посвящено разбору недочётов черновика C++17, несколько интересных и свежих идей успели обсудить, и даже привнести в стандарт то, о чём нас просили на cpp-proposals@yandex-team.ru.
Разбор недочётов
Основная задача прошедшей (и следующей встречи) — разбор и исправление замечаний к C++17 (если вы не в курсе крупных нововведений C++17, то вам сюда). Замечания были двух типов — комментарии от стран участниц WG21 и замечания от пользовательей/разработчиков стандартной библиотеки. Комментарии от стран, по традиции, разбираются в первую очередь (каждому комментарию присваивается идентификатор, состоящий из кода страны и последовательно возрастающего номера комментария). В этот раз пришло более 300 замечаний. Вот некоторые самые интересные и запомнившиеся из них:
RU 1: инициализация константных объектов
С 2000 годов в С++ есть проблема с инициализацией константных структур. Так, поведение компилятора внезапно зависит от ряда совершенно неочевидных факторов:
struct A0 {};
const A0 a0; // ошибка компиляции
struct A1 {
A1(){}
};
const A1 a1; // OK
struct A2 {
int i;
A2(): i(1) {}
};
const A2 a2; // OK
struct A3 {
int i = 1;
};
const A3 a3; // ошибка компиляции
Просьба исправить это поведение пришла к нам на cpp-proposals@yandex-team.ru от Ивана Лежанкина, мы с помощью людей из ГОСТ оформили его как комментарий от страны и… поведение исправили в C++14 и C++17. Теперь вышеприведённый код должен компилироваться.
Где это может быть полезно:
Крайне полезно при рефакторинге. Раньше удалив пустой конструктор можно было сломать компиляцию проекта:
// в заголовочном файле:
struct A1 {
A1(){} // Если удалить, сборка проекта сломается
};
// Код из проекта соседнего отдела
const A1 a1;
С исправленным RU 1 можно будет менять классы, удаляя пустые конструкторы, и код продолжит работать. При этом можно получить небольшой выигрыш в производительности: библиотеки, использующие метапрограммирование, порой имеют дополнительные оптимизации для классов которые std::is_trivially_constructible; компиляторы зачастую лучше оптимизируют те конструкторы, которые они сами сгенерировали и т.д.
RU 2: невалидное использование type traits
Замечательный способ выстрелить себе в ногу, не заметить и умереть от потери крови:
#include <type_traits>
struct foo; // forward declaration
void damage_type_trait() {
// Вызываем is_constructible для неполной структуры, что недопустимо.
// Однако согласно стандарту именно пользователь должен проверять
// валидность входных параметров, так что компилятор промолчит и скомпилирует код.
std::is_constructible<foo, foo>::value;
}
struct foo{};
int main() {
static_assert(
// Выдаст неверный результат, компиляция функции damage_type_trait()
// поломала std::is_constructible
std::is_constructible<foo, foo>::value,
"foo must be constructible from foo"
);
}
Лично я потратил неделю, выискивая подобную ошибку в boost::variant. Теперь WG21 обратила внимание на проблему и работает над её исправлением. Все шансы на то, что в C++17 будет исправлено и компилятор, увидев код с инвалидным использованием type_traits будет выдавать ошибку компиляции с сообщением, подробно описывающем причину проблемы.
Где это может быть полезно:
Поможет вам не делать трудно обнаружимых ошибок. Избавит разработчиков от множества неприятных сюрпризов при использовании optional и variant, конструкторы которых используют type_traits.
RU 4 & US 81: constexpr char_traits
Мы и США нашли один и тот же недочёт. Проблема заключается в том, что std::string_view имеет constexpr конструктор, но инициализация объекта всё равно будет происходить динамически:
#include <string_view>
// Ошибка компиляции:
// > error: constexpr variable 'service' must be initialized by a constant expression
// > constexpr string_view service = "HELLO WORD SERVICE";
// > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// > string_view:110:39: note: non-constexpr function 'length' cannot be used
//
constexpr string_view service = "HELLO WORD SERVICE";
В качестве исправления приняли наш фикс (Была принята версия версия p0426r1, она пока не доступна для общего пользования).
Где это может быть полезно:
Компилятор сможет лучше оптимизировать конструирование std::string_view, вы сможете использовать string_view в constexpr выражениях.
shared_ptr::unique()
Один из запросов был на то, что shared_ptr::unique() должен гарантировать синхронизацию памяти std::memory_order_acquire.
И тут мы поняли, что многие не знают как правильно пользоваться этой функцией в многопоточной среде. Так вот, правильное использование — не пользоваться.
Если shared_ptr::unique() вернул true и ваша имплементация гарантирует std::memory_order_seq_cst, то… это ничего не значит! Ситуация может поменяться сразу после вызова функции unique():
- в другом потоке может быть ссылка на этот shared_ptr и он как раз сейчас копируется
- в другом потоке может быть weak_ptr который вызывает lock()
В итоге, решено было пометить метод unique() как deprecated и подробнее расписать все проблемы в описании shared_ptr::use_count().
Присоединённые полиномы функции Лежандра
Один запрос, пришедший к нам на cpp-proposals@yandex-team.ru из МГУ от Матвея Корнилова, нам особенно запомнился. В нём описывалось много интересных вещей, связанных с математикой. Некоторые идеи сейчас в разработке самим автором, а некоторые удалось отправить как «редакторские правки» к стандарту и исправить прямо на заседании в Иссакуа, поговорив с одним из редакторов стандарта.
Так вот, одна правка которая особенно запомнилась, заключалось в том, что надо переименовать раздел «Associated Legendre polynomials». Потому что формула в разделе ну вот не представима в виде полинома :-)
От чего данная «школьная» ошибка улыбает меня ещё сильнее :-)
Прочее
- Std::variant не будет уметь хранить ссылки, void и C массивы (но вы всё ещё можете использовать std::reference_wrapper<T>, std::monostate и std::array чтобы добиться аналогичного поведения).
- Продолжается работа над добавлением deduction guildes к стандартной библиотеке. Есть все шансы на то что
std::array a = "Hello word";
будет работать из коробки. - На заседание пришли специалисты по zOS с некоторыми замечаниями к std::filesystem. В планах — успеть на следующем заседании внести модификации в стандарт, чтобы сделать std::filesystem ещё более универсальным инструментом.
- Специальный «тег»
std::in_place<тип-данных-или-число>
возможно уберут в пользу нескольких теговstd::in_place, std::in_place_index<число>, std::in_place_type<тип>
. Лично мне больше нравится прошлый вариант. Но большинству, включая самого автора идеи универсального тега, он разонравился.
Обсуждения и идеи
Как всегда, обсуждения и разбор ошибок проходили в нескольких подгруппах одновременно. Оказаться сразу в 5ти местах — задача сложная, так что все идеи пересказать из первых рук не получится. Вот самые интересные обсуждения, на которых мы побывали:
??? operator.() ???
Обсуждали альтернативный синтаксис и подход к operator.().
Старый синтаксис P0416R1 | Новый синтаксис P0352R0 |
---|---|
|
|
Другими словами, предлагается вместо operator.() использовать несколько более понятное «наследование, где о хранении объекта автор класса заботится сам». WG21 попросила автора работать дальше в этом направлении.
operator<=>()
operator<=>() или «operator spaceship» — это идея которая появилась из обсуждения автоматического генерирования операторов сравнения. Комитет был против того, чтобы начать генерировать операторы сравнения по умолчанию и против того, чтобы генерировать операторы сравнения с помощью конструкций вида bool operator<(const foo&, const foo&) = default;. Тогда в кулуарах родилась идея:
- Сделать оператор сравнения, возвращающий сразу значения less, equal, greater;
- При наличии этого оператора — генерировать все операторы сравнения;
Пока дальше обсуждения речь не заходила, но выглядит многообещающе.
Reflections
Заседала группа разрабатывающая compile-time рефлексию для C++. У них есть базовый функционал, который они уже почти готовы передавать для дальнейшего обсуждения в другие подгруппы и выпускать в виде TS (technical specification) — доработки к стандарту, с которой можно будет пользователям начинать экспериментировать, не дожидаясь новой версии основного стандарта.
Итоги
Люди на заседании обработали огромное количество комментариев к стандарту. Более 100 недочетов было исправлено, за что им огромное спасибо!
5ого декабря в Москве на встречу Российской РГ21 мы ждём в гости Маршалла Клоу (Marshall Clow) — председателя Library Working Group в WG21 C++, разработчика стандартной библиотеки libc++, автора Boost.Algorithm. На встрече мы расскажем о наших дальнейших планах и наработках, вы сможете задать интересующие вас вопросы по C++ и предложить свои идеи для C++2a; Маршалл же расскажет про Undefined Behavior.
Мы также рады представить вам официальный сайт рабочей группы stdcpp.ru для обсуждения идей для стандартизации, помощи в написании proposals. Теперь вы сможете поделиться своей идеей для включения в стандарт C++, узнать что о ней думают другие и обсуждать предлагаемые идеи другими разработчиками. Добро пожаловать!
Комментарии (87)
stepanp
01.12.2016 19:42+1нет модулей — не нужно
aTwice
01.12.2016 20:22поясните, пожалуйста
DistortNeo
01.12.2016 20:59-1Нужно избавиться, наконец, от рудимента с разделением на h и cpp:
1. Независимая трансляция каждого cpp-файла сильно замедляет процесс компиляции, особенно если используется большое количество инклюдов и шаблонного кода. Компиляция должна быть на уровне проекта, а не файла.
2. Сложность с подключением библиотек: статические библиотеки не являются самодостаточными, их нельзя просто взять и подключить, как в других языках. Изволь тянуть с собой кучу инклюдов и не забывать прописывать пути.
Но я сомневаюсь, что здесь будут подвижки. Переход на модули, например, поломает частичную специализацию шаблонов и кол, использующий директивы препроцессора. Это потребует переписывания всей стандартной библиотеки. Получится, фактически, не надстройка над C++, а новый язык.antoshkka
01.12.2016 23:51+13Давайте я вкратце и упрощённо распишу, как работают модули и что именно «тормозит при компиляции»:
Когда вы собираете проект, каждый cpp файл может компилироваться параллельно (это хорошо, отличная масштабируемость).
Однако, как правило, вы используете одни и те же заголовочные фалы в каждом cpp файле. За счет того, что компиляция различных cpp фалов никак не связана друг с другом, при каждой компиляции компилятор разбирает одни и те же заголовочные файлы… снова… и снова… Именно этот разбор и тормозит (заголовочный файл iostream весит более мегабайта, подключите 20 подобных заголовочных файлов — и компилятору придётся просмотреть и разобрать около 30 мегабайт кода при компиляции одного cpp файла).
Модуль — это набор файлов, собранных воедино и сохранённых на диск в понятном для компилятора бинарном виде. Таким образом, при подключении модуля, компилятор просто считает его с диска в свои внутренние структуры данных (минуя этапы открытия нескольких фалов, парсинга, препроцессинга и некоторых других вспомогательных вещей).
Дополнительный прирост скорости при компиляции будет получен за счёт того, что в модуле вы явно указываете его публичный интерфейс. То есть компилятор сможет сделать ряд оптимизаций ещё при создании модуля. Это сильно уменьшит затраты оперативной памяти, ускорит поиск подходящих перегруженных функций, структур и т.п за счёт того, что их будет просто меньше.
И наконец, финальная стадия сборки проекта — линковка. В данный момент линковщик много времени тратит на выкидывание одинаковых блоков скомпилированного кода (вы подключили iostream 100 раз — линкер выкинет 99 скомпилированных std::cout). С модулями есть шанс, что линкеру не придется этим заниматься, т.к. файл модуля не будет вкомпиливаться внутрь собранного cpp файла.
Модули ничего не ломают, иначе бы их не принимали в стандарт. Модули не будут автоматически генерироваться для вашего проекта. Вам придется постараться и описать публичные интерфейсы модуля, чтобы получить дополнительные плюшки модулей.hacenator
02.12.2016 00:08Ух ты! Какой большой ответ для человека который не понимает как устроен c++.
Еще можно добавить про precompiled headers на «используется большое количество инклюдов и шаблонного кода».
DistortNeo
02.12.2016 00:23Да, именно этим и занимались линковщики в 80-90-е годы, бездумно собирая программу из предоставленных объектных модулей. Сейчас же линковщик делает то же самое, что и компилятор — оптимизирует код: основное время линковщика тратится не столько на выбрасывание дублирующегося кода, сколько на межпроцедурную оптимизацию для программы целиком.
С помощью g++ можно, например, компилировать программу как единое целое, минуя создание объектников.Gumanoid
02.12.2016 01:03+4Межпроцедурную оптимизацию делает не линкер, а компилятор, который вызывается из линкера.
С помощью g++ можно, например, компилировать программу как единое целое, минуя создание объектников.
Если вызвать «g++ -flto file1.cpp file2.cpp», то объектники всё-равно создадутся (в /tmp), потом подадутся линкеру, и он опять позовёт gcc для перекомпилиции с межпроцедурными оптимизациями. Можно подать опцию -v и увидеть все подробности.
antoshkka
02.12.2016 01:03Да, именно этим и занимались линковщики в 80-90-е годы
И продолжают заниматься по сей день. Было бы неплохо, чтобы эта часть сборки происходила ещё быстрее :)
Daytar
01.12.2016 22:30+3Заканчивался 2016 год, а в STL так и нет ВООБЩЕ НИЧЕГО для кроссплатформенной работы с сокетами. И видимо ещё лет 6 не будет… Будем надеяться что хоть filesystem не выкинут туда же.
antoshkka
01.12.2016 23:13+2Networking в течение года должен появиться в виде TS (уже отправлен на утверждение его черновик). Сможете воспользоваться кроссплатформенными сокетами ещё до C++2a (возможно что даже до C++17).
monah_tuk
05.12.2016 07:09А мне вот отвратительно видеть, что в этом пропозале форсируется использование паттерна проактор (по сути весь Asio, как есть), тогда как на том же Linux/FreeBSD да и вообще всех Unix — реактор реализуется меньшими накладным расходами.
Т.е. моё мнение, что код для сокетов должен быть оторван от асинхронности. Абстракция над сокетами — отдельно. Асинхронная работа — отдельно. И вот тут бы было неплохо иметь возможность выбора стратегии.
Сама абстракция над сокетами же, работа с параметрами сокетов — мне нравится. Даже можно выпендриться и использовать только её, скрестив, допустим, с libev: когда игрался получился заметный выигрыш в попугаях на стендовом http сервере.
DistortNeo
02.12.2016 00:09Я бы написал ещё жёстче: в STL до сих пор нет средств для кроссплатформенной работы с файлами в целом, а не только с сокетами.
Ну а что касается сокетов: не хочется жертвовать производительностью ради универсальности. В драфтах, например, не планируется использование ни epoll, ни IO completion ports.antoshkka
02.12.2016 00:50Файловая система в C++17
В драфтах, например, не планируется использование ни epoll, ни IO completion ports.
Мы точно про одни и те же драфты говорим?DistortNeo
02.12.2016 01:03Мы точно про одни и те же драфты говорим?
Не знаю. Я вот этот драфт имел в виду:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4612.pdfantoshkka
02.12.2016 01:14+3В нём нет текста, запрещающего использование epoll или IOCP. Платформо специфичные вызовы не описываются в стандарте. Так например вы не найдете CreateThread в описании std::thread.
Драфт Networking основан на ASIO, активно разрабатывался тем же разработчиком и ASIO является прототипом к TS. Можете посмотреть на реализацию ASIO, и там вы найдёте использование epool, pool, select, iocp (в зависимости от платформы).
monah_tuk
05.12.2016 07:11+1не планируется использование ни epoll, ни IO completion ports.
я или что-то не то смотрел, но нетворкинг это практически Asio как есть. epoll/IOCP это детали реализации. Ну а то, что оверхеда с epoll больше за счёт эмуляции проактора на реакторе — это архитектурный прогиб под IOCP.
Satus
02.12.2016 00:51+2Раз уж зашла речь о предложениях, меня всегда интересовало, почему функции std::uninitialized_copy/fill/move не имеют перегрузок, которые принимают аллокатор как дополнительный параметр. Раз уж они внутри всё равно вызывают placement new, почему не сделать перегрузку, которая вместо этого вызывает allocator_traits::construct?
antoshkka
02.12.2016 09:51Похоже на дефект. Поузнаю поподробнее, возможно что к C++2a поправим.
Спасибо!
Gorthauer87
02.12.2016 00:56Лучше бы вместо костылей в виде оператора <=> запилили аналог derive из раста, решило бы ВСН проблемы с автоматической генерацией операторов.
antoshkka
02.12.2016 01:25Опишите пожалуйста вашу идею поподробнее. Чем это лучше?
Gorthauer87
02.12.2016 11:20Да хотя бы очевидностью процесса: если нам нужен конструктор копирования или операторы сравнения, то мы пишем #[derive(Clone, ParialEq)] и они только в этом случае генерируются. Эту идею можно совместить с концептами и все операторы выразить через них, а также много чего еще, к примеру обозначить уровень потокобезопасности класса или сгенерировать для него автоматически методы для сериализации/десериализации его полей.
LifeKILLED
02.12.2016 05:14+3Ну когда уже в C++ интегрируют Брайнфак, я устал ждать…
antoshkka
02.12.2016 09:18+2Надеюсь вы предлагаете Брейнфак, выполнимый на этапе компиляции!
Давайте уж лучше сделаемJava(слишком скучно), C#(слишком мейнстрим), Erlang (не модно), Node.js (hype спал, оно ещё живо?)Rust на шаблонах. В конце концов, надо успеть отдать должное этому языку, прежде чем он канет в Лету.</troll-mode>
Antervis
02.12.2016 06:46Интересно, когда появится constexpr new (для создания constexpr — объектов, мутабельные версии которых используют кучу)?
antoshkka
02.12.2016 09:10Я прям хочу этот функционал! Но международный комитет, как мне кажется, пока к нему не готов :)
Надо сначала разрешить виртуальные функции в constexpr выражениях и подкрутить правила работы с деструкторами в constexpr выражениях.
alexeykuzmin0
02.12.2016 11:14Товарищи, просветите, кто-нибудь: вот раньше при работе с последовательностями данных, по которым мне достаточно проитерироваться, я обычно писал функцию, принимающую пару итераторов: начало и конец (ну еще iterator_tag нужный требовал через enable_if) для того, чтобы можно было передать содержимое любого контейнера (или вообще читать через input_iterator). А сейчас у нас итераторы, я так понял, deprecated, а range еще не введены.
Какой православный метод предполагается в данном случае?antoshkka
02.12.2016 14:09+2Deprecated только вспомогательный класс std::iterator. Этим классом сложно пользоваться (я например не помню, в каком порядке передавать шаблонные параметры) и он бесполезен при написании шаблонных итераторов.
Остальные итераторы никто не трогал, ими всё ещё можно (и нужно) пользоваться.
leremin
02.12.2016 21:00Лучше бы стандартизировали декораторы имен (или что там мешает использованию классов в dll) и шаблонов там же. Впрочем, уже 3 года на C# сижу и не жалею.
sunnee
04.12.2016 15:15Всякие Properties и Extensions вещь конечно нужная, но жить без них вполне можно. И как уже было сказано выше, те же Properties реализуемы текущими средствами языка, кому нужно, тот допишет.
А вот поддержка UNICODE из коробки, так чтобы fopen (понятно, что он еще из C, но ведь из C++ никуда не делся), да что там, fstream::open принимал UTF8 на всех платформах, а не только на UNIX.
Хотелось бы, что-бы std::string умел работать с UNICODE, без проблем поддерживал композицию/декомпозицию и банальное сравнение без учета регистра (с учетом текущей локали), и поиск по строке (естественно с учетом разных форм записей одной и той же строки в UNICODE).
И после Objecive-C с их подсчетом ссылок, std::enable_shared_from_this кажется жесточайшим костылем. Я понимаю, что RAII важная и удобная концепция языка (чего не хватает многим java/C#/JS), но есть 2 проблемы:
— как быть, если объект с std::enable_shared_from_this создается на стеке?
— в целом хранение счетчика ссылок «далеко» от самого объекта существенно снижает производительность.
Я бы предложил создавать счетчик прямо в объекте (так быстрее и не нужны костыли), и запретить создавать такие объекты на стеке, еще на этапе компиляции!antoshkka
04.12.2016 15:25Хотелось бы, что-бы std::string умел работать с UNICODE, без проблем поддерживал композицию/декомпозицию и банальное сравнение без учета регистра (с учетом текущей локали), и поиск по строке (естественно с учетом разных форм записей одной и той же строки в UNICODE).
Да, это известные проблемы и над ними работают.
— как быть, если объект с std::enable_shared_from_this создается на стеке?
Просто не позволяйте так делать:
class foo: public std::enable_shared_from_this<foo> { foo() = default; public: static std::shared_ptr<foo> construct(); };
— в целом хранение счетчика ссылок «далеко» от самого объекта существенно снижает производительность.
std::make_shared решает эту проблему. Везде и всегда его используйте!
monah_tuk
05.12.2016 07:37Дайте аналог realloc. Хотя бы для простых, POD и trivially_copyable типов.
Не знаю, пусть будет хотя бы так:
new_ptr = new (old_ptr) Foo[new_size];
Для сложных типов вполне себе может быть сэмулирована как new[]/move/delete[].
Сигнатура для оператора может быть (что бы не конфликтовать с placement new):
void* operator new (size_t size, void *old_ptr, struct realloc_tag);
Такой синтаксис сейчас применим для placement_new с массивами, но может вызывать проблемы. Оно и понятно: особенно для non-POD нужно хранить где-то количество элементов, что бы конструкторы вызвать.
Поддержка со стороны языка нужна так как оператор ничего не знает о типах, он просто выделяет память. А уже операиця new, должна решить, в зависимости от типа: делать realloc или new/move/delete. Ну и ограничить применимость только для массивов, так как я слабо представляю необходимость такой процедуры для единичного элемента в памяти.
Antervis
05.12.2016 08:42так он по факту нужен для реализации контейнеров. А для общего назначения у нас всякие std::vector/std::string/… уже есть.
monah_tuk
05.12.2016 10:10Да, я согласен. Но иногда в тесных рамках embedded бывают ограничения на использование STL. Собственно там как раз такое и сильно треба бывает.
Antervis
05.12.2016 12:16тут уж как говорится «проблемы индейцев вождя не волнуют». Плюс, насколько я знаю, в контроллерах не комильфо выделять память через new.
monah_tuk
05.12.2016 13:55Контроллеры бывают разные: между AVR8 и PIC и Rapberry PI пространства очень много и оно далеко не пустое. Так что и аллокации в куче бывают нужны/позволительны. А вот ограничения на использование STL бывают, нередко, правда, чисто административного плана или саппортится не все низкоуровневые API (урезанный рантайм).
antoshkka
05.12.2016 13:02Разработчик libstdc++ сейчас продумывает механизм, позволяющий делать нечто подобное.
Возможно что к C++2a будет готово.
mezastel
Вот если бы меня спросили что надо улучшать в C++, я бы язык не трогал вообще. С языком все «норм». Нужно фиксить во-первых, либы т.к. STL — тихий ужас с точки зрения юзабельности (хотя обобщенные алгоритмы и выглядят корректно с точки зрения «обобщения» задач, их использование в 100 раз больнее чем, например, IEnumerable/LINQ). Нужен STL2 который будет сделан в стиле C#/Java — полные имена функций, удобоваримое преставление «перечисляемости» вместо пресловутых пар begin()/end(), вменяемые member functions, когда можно сделать `myvector.sort()` и не париться. Ну и STL нужно выводить на «бытовой» уровень — добавить например поддержку разных форматов (XML или PNG, например) из коробки, чтобы не надо было на каждый чих копать чужие сорцы, написанные во времена С.
Вторая проблема — это скорость компиляции. Конечно, хорошо сиделать на Cling и получать REPL от Clang (даже если вы под Windows), но все же хочется и компилировать во вменяемые сроки. А модули могли уже сделать ой как давно, но че-то до сих пор тянут резину.
В третьих, хочется чтобы закончились «пакетные войны» и С++ пришли к стандарту о пакет-менеджменте, даже если этот стандарт подразумевает локальную компиляцию. Rust эту проблему как-то решил, может решить и С++ если не пытаться делать из этого коммерческий продукт (привет, biicode) а просто зарелизить и хорошо пропиарить что-то работающее.
Но если уж вам действительно хочется порыться в языке в попытке сделать его лучше, то я бы предложил несколько простых вещей:
Вот пока все выше не сделано, обсуждать новые операторы и прочие извраты имхо рановато. Нужно сначала привести язык к состоянию, когда студент может на него посмотреть и его не будет тошнить от неудобоваримости увиденного. И вот тогда можно ваять новые фичи.
Да и насчет spaceship operator — если надо чтобы простой класс определял весь пакет операторов и сразу, посмотрите на Котлиновский data class, это как раз то что нужно.
antoshkka
Поддерживаю целиком и полностью! Вам интересно будет начать писать proposal+прототип и прорабатывать эту идею в stdcpp.ru?
Можете предложить синтаксис (здесь или на stdcpp.ru)?
() можно уже давно не писать.
«автоматом [=] для литералов вроде int32_t и [&] для всего остального» — ночной кошмар при отладке, суровая возможность убить себе производительность. Лично я очень не люблю [=] и [&], пожалуйста не надо делать их использование ещё проще.
Rezzet
Одна из самых больших болей в с++ c которой сталкивался, это использование в каждой более-менее большой библиотеке своих строк, своих типов для Vector3, Matrix4x4, отсутвие возможности в std сделать конвертацию cp1251 -> utf8 и обратно, необходимость всегда первым делом тащить в проект libpng, libjpg, libzip и прочее что уже стало неким стандартом, по хорошему я бы пол Qt в stdlib запихнул, особенно по части работы с форматами мультимедия. это даже более важное чем модули, которые кстати то же нужны, на с++ сейчас смешно без этого смотреть.
antoshkka
У меня нет большого опыта конвертации кодировок, работы с libpng и libjpg. Если у вас есть идеи о том, как правильно их внедрить в стандарт — пишите обязательно, постараюсь по максимуму вам помочь.
Vector3, Matrix4x4 — над подобными типами данных работают, но я не в курсе прогресса по ним. В C++17 их точно не будет.
DistortNeo
А почему нельзя ввести модули и оформить вышеописанные библиотеки как модули, которые было бы легко подключать?
Часть этих проблем, кстати, отсутствует, если писать под Windows (да, готов принимать помидоры за это утверждение). Изображения открываются через GDI+ абсолютно простыми и понятными методами. В WinAPI присутствуют функции для работы со строками с преобразованием CP??? <-> UTF-8 <-> UTF-16, есть CompressionAPI для работы с zip.
Отличие же libpng, libjpg и т.д. заключается в том, что они являются самостоятельными библиотеками, а не частью API операционной системы. Хорошо это или плохо — ответ неоднозначаный: хорошо, потому что отвязываемся от реализации в конкретной ОС, плохо — тащим с собой кучу кода, имеем проблемы с его подключением.
Antervis
нормальный API для работы со строками должен как минимум принимать на себя задачи по управлению памятью.
IRainman
И для DistortNeo тоже
В принципе особенных проблем с конвертацией сейчас нет, особенно из юникода в юникод.
P.S. просто скопипастил реализацию из своего проектика, на спецификаторы внимания не обращайте ;) С ANSI строками будет чуть сложнее, но задача тоже решаемая.
RPG18
А какую библиотеку лучше взять libjpeg, libjpeg-turbo или mozjpeg? Если запихнуть Qt в stdlib, то как часто мы будем получать новую версию? За 4 года Qt поменял версию с 5.0 до 5.7.
Antervis
во-первых, Qt в stdlib никто запихнуть не сможет. Во-вторых, чего вам не хватает в Qt 5?
RPG18
Я не говорил, что мне чего-то не хватает в Qt. Факт то что Qt постоянно развивается и версии выходят чаще, чем новые стандарты.
IRainman
В принципе при использовании std::locale и в целом Localization library уже сейчас можно спокойно написать конвертор для более простого конвертирования из ANSI локали в нужный UNICODE и обратно и внести его в стандарт, проблемы то нет особо. Там не особо большие изменения требуются.
mezastel
Я написал большое полотно но кнопка «Опубликовать» на сайте делает ровно ничего :(
antoshkka
Пожалуйста, напишите в личку, каким браузером пользуетесь, ОС и вышлите пожалуйста принтскрин.
0xd34df00d
Ranges требует concepts, что требует изменений самого языка.
Был пропозал с соавторством аж самого Страуструпа про unified call syntax.
А что это?
Пахнет выстрелом в ногу, особенно с такими правилами.
Как должен захватываться
class Foo { int32_t member; };
?class Foo { int32_t member [1]; };
?class Foo { int32_t member [1000]; };
?Можно аж с C++11 (если только вам не нужно указать mutable).
daiver19
Не могу согласиться по поводу «боли» от использования STL. vector.sort() — это, конечно, несколько более лаконично, вот только если вдруг вам понадобится отсортировать не весь вектор, так сразу почувствуется вся неуниверсальность такого подхода. Я уже молчу о, например, совместимости с C-массивами, которые пока что из стандарта никуда не делись, да и вряд ли денутся.
Сахар в духе Properties, конечно, неплох, но не так уж он и нужен. Никто не запрещает вам иметь get/set методы. Extension методы вообще относительно спорная штука.
Есть куча других нужных вещей, которых еще нет, я не спорю. Но добавление нового способа делать то, что и так уже нормально работает из коробки — это ИМХО, не должно быть приоритетом.
IRainman
Да, но таки меня вот, например, иногда критикуют за то что я, вынужденно, использую для генерации get/set методов и ещё много где для генерации кода макросы. Properties и прочий синтаксический сахар эту проблему решили бы и для меня и для всех критикующих тоже :)
Собственно у меня проблем нет и Properties мне не сильно нужны, но приходиться писать как то так иногда:
У многих это вызывает БООООЛЬ ;)
IRainman
P.S. «CONST» это не опечатка это тоже вынужденная мера поскольку код используется сразу на нескольких сильно разных платформах, одна из которых вообще микроконтроллер и там очень тяжко с ресурсами и местами сильно плохо в целом, typedef не спасает ибо не везде работает и в итоге там вот такое безобразие:
Такой вот он IoT :)
RPG18
Мало библиотек сорцами времен C++11?
eiskalt
Есть ли пример «проверенного» SAX XML парсера на C++11?
IRainman
Присоединяюсь к вопросу eiskalt, покажите, пожалуйста, пример библиотеки для работы с XML, или любыми форматами картинок на C++11 ибо всё мне известное использует либо C++03/98 либо вообще голый C с интерфейсами C++03 :(
P.S. искать мне не лень и самому, но я уже давно не могу найти работающую замену старым решениям, к сожалению.
GamePad64
Есть такой проект, от создателей biocide: conan.io. Вроде интересен сам по себе: не зависит от системы сборки, неитрузивный, можно поднимать локальный репозиторий. Но репозиторий почти пуст, коммитят в них полтора человека, да и те — авторы проекта. Непонятно, будет он жить, или нет (вроде, обещают интеграцию с Artifactory), но с технической точки зрения — штука интересная.
antoshkka
Выглядит многообещающе. Но вот у одной компании есть NuGet, и отказываться от него они не собираются.
Нужно чтобы conan.io научился работать с NuGet, а NuGet с conan.io. Тогда, наверное, проблемы со стандартизацией будут решаемые.
stepik777
NuGet больше для C#, а для плюсов — vcpkg.
KindDragon
Да, vcpkg выглядит хорошо — как apt-get для Windows.
Вот сравнение с NuGet и Conan.io
Gorthauer87
Ну на первый взгляд он выглядит так, будто его не проблема и на линуксе завести, хотя использовать для описания пакетов cmake немного странно выглядит, но с другой стороны это должно как-то легко приделываться к любому другому cmake проекту.
GamePad64
Нет, оно там гвоздями к винде приколочено, разрабатывалось без оглядки на другие ОС (а жаль, имхо, оно лучше, чем conan)
Gorthauer87
Приколотить гвоздями к винде cmake нужно еще постараться, он же crossplatform. Таланты блин)
AxisPod
Язык уже превратился в такой ком костылей и всего прочего, что нужен просто другой язык. А stl надо не просто фиксить, а очень быстро развивать, ибо грызть этот кактус становится уже больно.
>> Extension methods
Поиспользовал в C#, уже нет особого желания их использовать, особенно когда в них начинают пихать нереальных размеров всякий бред, сложную логику и работу с БД. С одной стороны полезно, в комбинации с адекватными лямбдами можно сделать без боли в одном месте аналог linq (C#) и streams (Java), но по ощущениям не самая важная вещь. Уж лучше asio перетащить в stl, пользы будет больше, да хотя бы boost::di докинуть.
>> Properties, т.к. они проверены временем и реально нужны
Я бы сказал, хорошо там где нас нет. Пожив в C#, почитав Рихтера, пришло понимание, что может быть данная концепция и удобна, но постоянные злоупотребления приводят к очень неприятным последствиям. Меняете свойство, ожидаете одно поведение, а ловите непонятно что. То дедлок, то эксепшен, то меняются другие свойства, то еще куча всего. В итоге я бы не стал трогать, кому надо, тот сделает себе эти самые свойства существующими средствами языка.
Лямбды, надо смотреть в сторону других языков, я не понимаю, зачем надо описывать захваты, если в большинстве случаев можно определить из контекста. $0, $1 вот не надо такого счастья, не могу ничего доброго вспомнить о Perl с его невообразимой куче всяческих переменных такого вида. Разбираться в таком коде и врагу не пожелаешь.
antoshkka
Мне кажется что в большом количестве случаев, определить из контекста невозможно:
Хотел тут пользователь передать «a» по ссылке или по копии? Формализовать логику копия/ссылка будет очень тяжело, она может значительно замедлить компилятор и приводить к не очевидному поведению.
DistortNeo
Я их использую как альтернативу плюсовому функционалу по специализации шаблонов.
И очень не хватает перегрузки операторов в C# для дженериков: почему extension-методы допустимы, а перегрузки операторов (суть то же самое) — нет?
hacenator
По моему Properties уже давно успешно реализуются через темплейты.
Extension methods конечно хорошо, но затруднит читаемость кода.
Ну а с лямбдами всё спорно, изначально у них странный синтаксис. Меня всегда особенно беспокоил возвращаемый тип через '->', это уж совсем как-то мерзковато.
STL уже давно никуда не годиться, и работать с ним не удобно и выглядит всё порой страшновато, да и много нужных вещей не хватает. Но с другой стороны новый STL2 тоже ни к чему, к хорошему это не приведет, т.к. все сразу захотят свой STL.
Ну это очень спорно. Когда уже долго пишешь на плюсах его синтаксис начинает казаться идеалом.
DistortNeo
По-моему, нужен просто новый удобный диалект C++, который был бы семантически идентичным C++, но синтаксически несовместимым с ним. Все проблемы растут от того, что C++ прирастал костылями, вместо того, чтобы перерасти в новый язык.
hacenator
Так может тогда проще писать на C#?
DistortNeo
Так я и пишу на нём. На C++ переключаюсь только для написания вычислительного кода (обработка изображений).
Antervis
у них лаконичный синтаксис
а в чем проблема? Во многих яп используется такой синтаксис. Особенно с учетом того, что в большинстве случаев указывать тип возвращаемого значения не нужно.
едва ли идеалом, но полный контроль над происходящим — то, к чему привыкаешь и чего в большинстве языков нет и никогда не будет.