Проблема с инициализацией объекта из списка инициализаторов

У меня есть следующий код:

    class A {
public:
A(std::vector<std::shared_ptr<int>>){}
};

auto x = std::make_shared<int>(0);
auto y = std::make_shared<int>(1);

auto list = {x, y};
auto res = std::make_shared<A>({x, y});

В примере, если я перехожу к списку переменных res, он компилируется, в противном случае, как в случае непосредственного использования списка инициализаторов, происходит сбой http://ideone.com/8jYsDY

Я предполагаю, что это связано с тем, как работает вывод типов, когда задействован initializer_list. Если это стандартное соответствие, некоторые ссылки будут хорошими.

1

Решение

std::make_shared выводит свой второй параметр шаблона из аргументов вызова функции. Braced-init-list не является выражением и поэтому не имеет типа. Следовательно, вывод аргумента шаблона не может вывести тип из него.

От §14.8.2.5 / 5 [temp.deduct.type]

Неведуемые контексты:
  — ...
  — параметр функции, для которого связанный аргумент является списком инициализатора (8.5.4), но параметр не имеет std::initializer_list или ссылка на возможно cv-квалифицированное std::initializer_list тип. [ Пример:

 template<class T> void g(T);
g({1,2,3}); // error: no argument deduced for T

— конец примера ]

autoОднако это особый случай, который позволяет вывести std::initializer_list<T> из списка инициалов.

§7.1.6.4 / 7 [dcl.spec.auto]

... В противном случае, получить P от T заменив вхождения auto либо с новым параметром изобретенного типа шаблона U, либо, если инициализатор приготовился-INIT-лист, с std::initializer_list<U>, Выведите значение для U используя правила вывода аргументов шаблона из вызова функции (14.8.2.1), где P тип параметра шаблона функции, а инициализатор — соответствующий аргумент. Если вычет не удался, декларация неверна. В противном случае тип, выведенный для переменной или возвращаемого типа, получается путем подстановки выведенного U в P, [ Пример:

 auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int>
auto x2 = { 1, 2.0 }; // error: cannot deduce element type

— конец примера ]

В вашем примере переменная list имеет тип initializer_list<shared_ptr<int>>и когда вы передаете его make_shared, vector может быть построен из него, который затем используется для прямой инициализации A пример.

Другие варианты — построить vector

auto res = std::make_shared<A>(std::vector<std::shared_ptr<int>>{x, y});

построить A, который затем будет перемещен

auto res = std::make_shared<A>(A{{x, y}});

или укажите параметры шаблона для make_shared эксплицитно

auto res = std::make_shared<A, std::initializer_list<std::shared_ptr<int>>>({x, y});
1

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector