Так в этом и проблема: если до сих пор машины заменяли труд человеческих рук и ног, то сейчас начинают заменять труд мозга и глаз. А это последнее, что оставалось у человека лучше, чем у машин.
По поводу custom deleter — «не поддерживает» и «не возможно сказать устновлен ли» — это разные характеристики, не правда ли?
Вот тут Вы не правильно поняли.
В статье я говорю, что невозможно сказать, как именно поведёт себя экземпляр std::shared_ptr, т.е. как он создан — с помощью конструктора или с помощью std::make_shared. Разница в поведении существенная (настолько существенная, что это могли бы быть даже разные статические типы), а выяснить это нельзя.
Существенная часть посыла статьи: «контекст, в котором родился std::make_shared, существенно изменился с приходом c++17».
Далее, Вы говорите про производительность.
Да, это важный параметр.
Но:
— std::make_shared не гарантирует повышение производительности. Если бы была функция std::make_single_allocation_shared — вот тогда да, в точку;
— с нехваткой производительности на std::shared_ptr реально столкнуться тогда, когда их в самом деле 100 000. И если бы я на практике такое встретил — выруливал бы не в сторону экономии одной аллокации (всё равно ведь не спасёт), а действительно, как говорит destman, или в сторону кастомного решения со строго необходимым функционалом, или в сторону уменьшения количества разделяемых объектов до единиц — десятков.
Мне вот не совсем понятно.
Почему не использовать std::unique_ptr? Неужели вам в самом деле надо разделять владение? А если и так — почему надо разделять владения 100 000 объектов, а не одного объекта, содержащего 100 000 элементов?
Нет, не так.
Я начал с истоков — почему std::make_shared был прямо жизненно необходим. Потому что утечки — это серьёзная проблема. И с утечками sdt::make_shared действительно борется успешно. Или боролся. До c++17. И до c++17 действительно можно было просто применять std::make_shared, даже толком не вникая в подробности. Потому что это решало критичный, первостепенный вопрос. Не читая документации, не разбираясь — просто применять готовый рецепт.
А Вы сейчас — про производительность.
Так вот, производительность — вопрос вторичный. Кому-то может её хватать, а кому-то — нет. Способов оптимизации — масса. Критичность недостаточной производительности как правило намного ниже, чем текущей памяти, которая может заканчиваться крэшами.
Одна аллокация и деаллокация вместо двух — это положительная сторона медали (но, заметьте — она не гарантирована). Но она же обязательно влечёт вторую сторону, отрицательную.
Будет ли для вас отрицательная сторона заметна — это вопрос.
Как впрочем и положительная.
Но это совсем не повод утверждать, что отрицательное — это не отрицательное, или что его нет.
Просто документацию читать надо перед тем, как что-то использовать
Статьи на хабре вообще не нужны. Учебники тоже. И комментарии. И обсуждения. И форумы. Это всё для слабаков, которые не умеют читать справочники.
Это довольно странная и неочевидная особенность, что способ создания существенно влияет на поведение объекта, при этом спросить объект в рантайме «ты чьих будешь» никак нельзя.
Т.е. этот умный указатель предъявляет требования к хранимым типам? И совсем не способен хранить без обёртки простые типы, контейнеры стандартной библиотеки, классы сторонних библиотек?
Спасибо, в самом деле, моя ошибка.
Исправил статью.
И дополнил в соответствии с возможностью поуправлять ещё одним возвращаемым значением.
Плюсик Вам в карму.
Так в этом и проблема: если до сих пор машины заменяли труд человеческих рук и ног, то сейчас начинают заменять труд мозга и глаз. А это последнее, что оставалось у человека лучше, чем у машин.
Вот тут Вы не правильно поняли.
В статье я говорю, что невозможно сказать, как именно поведёт себя экземпляр std::shared_ptr, т.е. как он создан — с помощью конструктора или с помощью std::make_shared. Разница в поведении существенная (настолько существенная, что это могли бы быть даже разные статические типы), а выяснить это нельзя.
Далее, Вы говорите про производительность.
Да, это важный параметр.
Но:
— std::make_shared не гарантирует повышение производительности. Если бы была функция std::make_single_allocation_shared — вот тогда да, в точку;
— с нехваткой производительности на std::shared_ptr реально столкнуться тогда, когда их в самом деле 100 000. И если бы я на практике такое встретил — выруливал бы не в сторону экономии одной аллокации (всё равно ведь не спасёт), а действительно, как говорит destman, или в сторону кастомного решения со строго необходимым функционалом, или в сторону уменьшения количества разделяемых объектов до единиц — десятков.
Про особенности вычисления аргументов тему я тоже поднял. Именно потому, что это важно и в данном контексте, и вообще для разработчика c++.
Почему не использовать std::unique_ptr? Неужели вам в самом деле надо разделять владение? А если и так — почему надо разделять владения 100 000 объектов, а не одного объекта, содержащего 100 000 элементов?
Я начал с истоков — почему std::make_shared был прямо жизненно необходим. Потому что утечки — это серьёзная проблема. И с утечками sdt::make_shared действительно борется успешно. Или боролся. До c++17. И до c++17 действительно можно было просто применять std::make_shared, даже толком не вникая в подробности. Потому что это решало критичный, первостепенный вопрос. Не читая документации, не разбираясь — просто применять готовый рецепт.
А Вы сейчас — про производительность.
Так вот, производительность — вопрос вторичный. Кому-то может её хватать, а кому-то — нет. Способов оптимизации — масса. Критичность недостаточной производительности как правило намного ниже, чем текущей памяти, которая может заканчиваться крэшами.
Будет ли для вас отрицательная сторона заметна — это вопрос.
Как впрочем и положительная.
Но это совсем не повод утверждать, что отрицательное — это не отрицательное, или что его нет.
Статьи на хабре вообще не нужны. Учебники тоже. И комментарии. И обсуждения. И форумы. Это всё для слабаков, которые не умеют читать справочники.
if statement
«declaration of a single non-array variable with a brace-or-equals initializer»
Исправил статью.
И дополнил в соответствии с возможностью поуправлять ещё одним возвращаемым значением.
Плюсик Вам в карму.
Про ТБ желательно всё же указывать.
Вроде бы можно написать operator|| для указателей на функции.
Но нет. Потому что это встроенный тип.
Более-менее внятную диагностику дают Clang и MSVC.
www.godbolt.org/z/UraL8c