Конкретно: direct-list-initialization (cppreference.com(3)).Есть ли причина, по которой std :: make_shared/std :: make_unique не использует инициализацию списка?
Оба std::make_shared
и равномерной инициализации функции были введены в C++. Таким образом, мы можем использовать инициализацию агрегата при распределении объектов в куче: new Foo{1, "2", 3.0f}
. Это хороший способ непосредственно инициализировать объекты, которые не имеют конструкторов, такие как агрегаты, стручки и т.д.
А реальных сценарии, такие как декларирование случайных структур внутри функции, эффективно поставлять набор аргументов лямбда стал очень распространенным явлением, в моем опыте:
void foo()
{
struct LambdaArgs
{
std::string arg1;
std::string arg2;
std::string arg3;
};
auto args = std::make_shared<LambdaArgs>(LambdaArgs{"1", "2", "3"});
auto lambda = [args] {
/// ...
};
/// Use lambda
/// ...
}
Здесь auto args = std::make_shared<LambdaArgs>("1", "2", "3");
whould быть хорошо, но это не будет работать, потому что std::make_shared
обычно реализуется как:
template<typename T, typename... Args>
std::shared_ptr<T> make_shared(Args && ...args)
{
return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
}
Итак, мы застряли с auto args = std::make_shared<LambdaArgs>(LambdaArgs{"1", "2", "3"});
.
Проблема, которая должна была быть решена с помощью std::make_shared
, по-прежнему сохраняется для объекта без конструктора. И обходной путь не только неэстетичен, но и менее эффективен.
Это другой надзор или есть некоторые причины, которые защищают этот выбор. В частности, какие подводные камни могут быть в решении инициализации списка? std::make_unique
был введен позже, в C++ 14, почему он тоже следует тому же шаблону?
Не ответ на ваш вопрос, но обходной путь: если вы используете кортеж вместо случайной структуры, вам будет предоставлен соответствующий конструктор, и это даже терьер: 'using LambdaArgs = std :: tuple '; –
Frank
Проблема 'std :: make_shared' заключается в том, чтобы убедиться, что все очищено правильно, если исключение выбрано после создания объекта, но до того, как shared_ptr переходит в собственность. С учетом сказанного это выглядит как незначительный надзор. – Kevin
Вы можете найти это интересно: http://stackoverflow.com/questions/24234480/stdmake-shared-with-stdinitializer-list – marcinj