Open apolukhin opened 3 years ago
Павел, 7 августа 2017, 17:01
На данный момент, если написать make_shared
Как ваше предложение могло бы быть реализованно в стандарте и в компиляторах? Мне абсолютно не понятен механизм :(
Antervis, 15 августа 2017, 14:03 можно добавить специализацию make_shared как friend
yndx-antoshkka, 15 августа 2017, 14:24 Antervis, не поможет. Нужно ещё добавить allocate_shared и возможно какие-то внутренности конкретной имплементации стандартной библиотеки.
Дмитрий, 16 августа 2017, 9:50 Можно просто сконструировать объект снаружи и засунуть его как rvalue в make_shared. В C++17 при этом не должно произойти ни копирования, ни переноса.
yndx-antoshkka, 16 августа 2017, 13:32 dmitriy@izvolov.ru, вы подняли очень интересную тему! В данный момент так не работает https://godbolt.org/g/V3edfK . Если сделать чтобы работало - будет ооочень круто, rvalue будут более легковесными и будут работать с copy elision.
Однако это поменяет порядок следования вызовов. И может быть неприятно в ряде случаев. Я обдумаю и обсужу с разработчиками компиляторов.
Дмитрий, 16 августа 2017, 14:57 yndx-antoshkka, действительно, как-то я слишком оптимистично отнёсся к "copy elision". Но с интересом жду результатов обдумывания и обсуждения.
Перенос предложения: голоса +3, -5 Автор идеи: fgenatre
В нынешнем виде std::make_shared<>() не позволяет конструировать объекты с приватным конструктором даже при вызове из подходящего контекста (разве что только с некоторыми ухищрениями, типа наследования пустого производного класса и создания его экземпляра или объявлении вызываемой функции как friend для создаваемого класса). Между тем, на текущий момент не видно каких-либо серьезных преград разрешить использование std::make_shared<>() для объектов с приватными конструкторами.
std::make_shared<>() имеет ряд преимуществ перед обычным конструированием std::shared_ptr - к примеру, память и выделяется за один раз, а не за два (согласно рекомендации в стандарте), и сам объект и счетчик ссылок на него распалагаются в куче рядом (что в некоторых случаях может дать небольшой плюс в плане оптимизации). В нынешнем виде std::make_shared<>() не позволяет конструировать объекты с приватным конструктором даже при вызове из подходящего контекста (разве что только с некоторыми ухищрениями, типа наследования пустого производного класса и создания его экземпляра или объявлении вызываемой функции как friend для создаваемого класса). Между тем, на текущий момент не видно каких-либо серьезных преград разрешить использование std::make_shared<>() для объектов с приватными конструкторами - компилятору понадобится просто определить допустимость подобной операции в зависимости от контекста вызова (как сейчас при обычном создании shared_ptr).
Бонусом можно еще разрешить использовать make_shared<>() с фабричными методами, возвращающими сырой указатель (типа SomeObject* SomeObject::create(), например при использовании сторонних библиотек) - только там заранее неизвестно какой объект вернется (может быть сконструирован объект одного из унаследованных классов), следовательно, заранее память не аллоцируешь, и как вариант, компилятор может генерировать вариант фабричного метода, в котором вместо 'new' будет вызываться make_shared, и сконструированный умный указатель будет передаваться в вызываюшую функцию
Плюсы: упрощение кода и улучшение читаемости.