Как стать автором
Обновить
61
0
Дмитрий Пономарев @dm_frox

Программист

Отправить сообщение
Спасибо, что обратили внимание. Вообще автоопределение типа по списку в фигурных скобках может дать сюрпризы, здесь правила несколько запутанны. Например массив нельзя объявить auto, я писал об этом. Надо каждый раз проверять, что результат будет ожидаемый. Ну а печалится, что std::array побитово не совпадает с массивом, по моему, не стоит. Мы не должны программировать полагаясь на знание внутренней структуры объекта, мы должны использовать только интерфейс.
Спасибо! Сейчас вспоминаю, что и я когда-то с такими штучками сталкивался, правда довольно давно.
Это иллюстрация довольно известного совета — никогда не работайте с массивами в полиморфном стиле, через базовый класс.
Попробовал в MSVS 2019 standard C++17.
struct S
{
	int x;
	int z[];
};

Действительно компилируется, предупреждение Warning C4200 nonstandard extension used: zero — sized array in struct / union
Но память под такой массив не выделяется. Попытка доступа компилируется, но при выполнении ошибка: выход за границу стека. При попытке сделать такую структуру базовой или членом возникает ошибка. Не понятно, как это можно использовать (ну может быть только в union).
Спасибо! Честно говоря не знал. Но _countof() MinGW тоже поддерживает.
Спасибо! Рад, что формат понравился. Надеюсь через пару недель будет еще статья. Действительно пользовательские new/delete используются редко (лично я сам никогда). Но мне хотелось закрыть тему про перегрузку в C++ и без пользовательские new/delete это бы не получилось.
Я бы включил эти вопросы в статью про тривиальные типы и неинициализированные переменные. Тема на самом деле довольно интересная, правда материала не очень много, так на пару страниц.
int является тривиальным типом, поэтому при выполнении new int[42] для элементов не будет вызван конструктор по умолчанию (который для int просто обнуляет) и вектор будет инициализирован случайными значениями. Для не тривиальных типов гарантирован вызов конструктора по умолчанию. Два других варианта как раз и гарантируют вызов конструктора по умолчанию для любых типов, в том числе и тривиальных и в приведенных примерах вектор будет обнулен. Вариант с фигурными скобками позволяет задать произвольные инициализирующие значения для элементов вектора.
Согласен, что кастомные аллокаторы вещь довольно редкая. Аллокаторы для стандартных контейнеров тема весьма обширная, требует отдельной статьи. Именно там уместно обсудить pmr. На первый взгляд pmr ничего особенного из себя не представляют, достаточно традиционная кастомизация аллокатора с помощью виртуальных функция. Небольшие дополнительные накладные расходы на вызов виртуальных функций и за это полное отделения интерфейса от реализации. Я пока эту тему глубоко не копал, может там действительно есть что-то интересное.
Конечно получится плохо. Вообще using-директива в заголовочном файле относится к запрещенным приемам. Описанная возможность носит скорее абстрактный характер, служит для лучшего понимания архитектуры стандартной библиотеки и каких-то экспериментов. Лично я вообще никогда не использую using-директиву (правда, никогда не говори никогда). Так, что надо не поленится и ручками определить все операторы.
В контейнерах и алгоритмах, использующих operator<, есть понятие эквивалентности (не больше и не меньше). Конечно, это почти всегда совпадает с результатом применения operator==, но теоретически это может быть не так.
MSVS 2017 очень хорошо, я в свое время делал довольно много проверок. Надо только включить соответствующую опцию компилятора (по умолчанию она выключена). Ну в MSVS 2019 надо уже обсуждать поддержку C++20.
Конечно так правильнее. Но C-строки носят скорее иллюстративный характер, а не практический и мне хотелось продемонстрировать hash_combine, которую можно использовать гораздо шире.
MSVS 2017 очень хорошо, я в свое время делал довольно много проверок. Надо только включить соответствующую опцию компилятора (по умолчанию она выключена). Ну в MSVS 2019 надо уже обсуждать поддержку C++20.
Этот вариант обсуждался в одной из книг списка литературы. Он признан неудачным по причине приоритета оператора. У возведения в степень традиционно высокий приоритет, выше чем у умножения, а у ^ довольно низкий, и поэтому надо будет ставить скобки там, где их никто не привык ставить. Надо будет писать 2*(x^2) вместо привычного 2*x^2. Но и, соответственно, куча трудно обнаруживаемых ошибок.
Да, я писал, что чаще всего такая ситуация является неожиданной для программиста. Но Dura lex sed lex (Закон суров, но это закон).
Алгоритм здесь такой. Сначала ищутся точно подходящие нешаблонные функции и конкретизации шаблонов, полные специализации шаблонов на этом этапе вообще не рассматриваются. В нашем случае есть две точно подходящих конкретизации: шаблон 1 для const char* и шаблон 2 для char. Выбирается шаблон 2 как более специализированный. Далее проверяется, нет ли у этого шаблона полной специализации для выведенного аргумента — char. В нашем случае нет, поэтому этот шаблон и выбирается окончательно.
ADL — это стандарт языка и довольно старый. Без него было бы очень неудобно использовать перегрузку операторов. Перегрузке операторов посвящена следующая статья этой серии, которую планирую выложить через несколько дней.
Спасибо! По поводу отсутствия объяснений, ПОЧЕМУ это так работает ответ достаточно традиционный — ограничения объема статьи. C++20 у меня пока в начальной стадии изучения, но уже чувствую, что придется поработать.
Спасибо! Эта серия как раз и задумана как что-то вроде учебника для intermediate уровня.

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Зарегистрирован
Активность