Closed apolukhin closed 3 years ago
Andrey Davydov, 19 декабря 2018, 19:10 Кажется, что принятый в C++20 proposal http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0960r1.html делает ненужным Ваше предлажение.
Олег Фатхиев, 19 декабря 2018, 20:36 Andrey Davydov, действительно, это решает одну из проблем. Вызов list initializing это не чинит.
Andrey Davydov, 20 декабря 2018, 8:58 Олег Фатхиев, что Вы имеете в виду? Какой из Ваших примеров это не чинит?
Если что, std::vector считается ненормальным, классы для которых, X(2, 5) и X{2, 5} означают разное считаются ошибкой природы, и ради них создавать новый механизм (std::aggregate) это черезчур.
Олег Фатхиев, 20 декабря 2018, 15:15 Andrey Davydov, получается, что любой класс, имеющий конструктор от std::initializer_list, ненормальный?
Andrey Davydov, 20 декабря 2018, 15:35 Олег Фатхиев, ок, т.е. речь идет именно о классах конструирующихся от std::initializer_list? Для них есть неоднозначность, которую можно решать, предложенным Вами способом (только имя std::aggregate будет не очень удачным), а можно и не решать, так ли хуже
std::make_shared<std::vector<int>>(std::initializer_list{5, 2})
чем предлагаемый Вами
std::make_shared<std::vector<int>>(std::aggregate, 5, 2)
?
Теперь по поводу "ненормальных" классов. Я, наверное, резко выразился, но ситуация когда для класса {} и () инициализация приводит к разным результатам действительно крайне специфичная. Она же встречается не для любого вектора и любых аргументов, а только вектора целых чисел, конструирующегося от 1-2 аргументов. И да, я думаю, что возникновение подобных ситуацией это проблема в дизайне std::vector.
Анатолий Томилов, 26 декабря 2018, 15:28 Andrey Davydov,
std::initializer_list -- это ведь обязательное поэлементное копирование (именно копирование и именно неизбежное).
Andrey Davydov, 26 декабря 2018, 15:44 Анатолий Томилов, да, и что? Мы же все равно собираемся создавать std::initializer_list и передавать его в конструктор нашего класса, на важно в какой момент это делать -- внутри функции make_shared или снаружи от нее.
Antervis, 21 декабря 2018, 11:13 во-первых, лучше сразу ориентироваться на std::in_place_t, решающий именно такую задачу для variant/any/optional. Во-вторых, наверно, лучше сделать не только перегрузку make_unique/make_shared, а также перегрузки конструкторов unique_ptr/shared_ptr. По крайней мере с появлением deduction guides потребность в make_фунциях сильно снизилась.
yndx-antoshkka, 26 февраля 2019, 15:24 P0960 приняли в C++20. В std::aggregate_t смысл отпал.
Перенос предложения: голоса +7, -0 Автор идеи: Олег Фатхиев
Часто бывает нужно создать объект через aggregate initialization или list initialization. Когда речь идет о объектах в куче, мы используем std::make_unique или std::make_shared. Однако они не могут вызвать list или aggregate initialization (и правильно делают). Предлагаю добавить тэг std::aggregate, который будет говорить о том, что объект нужно создать с помощью aggregate или list initialization.
Бывает нужно, чтобы работал такой код:
std::make_unique пытается вызвать конструктор у some_aggregate_t, вместо aggregate initialization. Поведение ожидаемое и понятное, но хочется уметь создавать такие объекты без необоходимости дописывать конструктор.
Еще один пример:
В данном коде создается вектор с 5-ью 2-ками.
Предлагается добавить tag type std::aggregate_t, позволяющий специализировать вызов std::make_unique и std::make_shared:
Возможная реализация std::make_unique: