Я хочу создать класс, который будет вести себя так же, как класс, вокруг которого он находится. то, что я получаю, это ошибка компиляции, когда я пробую что-то вроде этого:
#include<vector>
#include<concepts>
template<class C1>
struct wrapper{
C1 p1;
wrapper():p1(){}
wrapper(wrapper&& o): p1(std::move(o.p1)){}
~wrapper(){p1.~C1();}
template<class ...C>
wrapper(C... c)requires std::constructible_from<C1,C...>:p1(std::forward<C>(c)...){}
};
//using namespace set_model;
int main() {
using w=wrapper<std::vector<float>>;
w a(5,1.2);
w b{std::vector<float>{1.2,1.7,1.9}};
//w c{1.2,1.7,1.9}; error:no matching constructor
//w d{{1.2,1.7,1.9}}; error:no matching constructor
std::vector<float> e{{1.2,1.7,1.9}};
return 0
}
конструкторы, найденные в исходном коде, похоже, здесь работают, но не Initializer_list! есть идеи, как заставить оболочку вести себя точно так же, как класс, который она обертывает, в данном случае std::vector? в b видно, что вектор инициализируется списком в фигурных скобках, в e также принимаются фигурные скобки внутри фигурных скобок. однако то же самое для класса-обертки не будет работать. нужно ли мне предоставить конструктор Initializer_list? почему созданный по умолчанию вариант не соответствует требованию?





Заключенная {} вещь не является выражением. У него нет типа.
{} вложенные списки выражений можно использовать для инициализации вещей, но сами по себе их нельзя использовать для определения типа чего-либо.
C++ не поддерживает идеальную переноску. Вы можете стать ближе, если сделаете несколько изменений
template<class C1>
struct wrapper{
C1 p1;
wrapper() = default;
wrapper& operator=(wrapper&& o)& = default;
wrapper& operator=(wrapper const& o)& = default;
wrapper(wrapper&& o) = default;
wrapper(wrapper const& o) = default;
~wrapper() = default;
template<class ...Cs>
wrapper(Cs&&... cs)
requires std::constructible_from<C1,Cs...>
:
p1(std::forward<Cs>(cs)...)
{}
template<class Is, class ...Cs>
wrapper(std::initializer_list<Is> il, Cs&&... cs)
requires std::constructible_from<C1,std::initializer_list<Is>, Cs...>
:
p1(il, std::forward<Cs>(cs)...)
{}
};
здесь я исправил ваш глючный деструктор и сделал все ваши специальные функции-члены =default.
Поскольку у wrapper<blah> есть std::initializer_list ctor (даже шаблонный), ваш {} теперь пытается сопоставить его (и добивается успеха).