С++. Перегрузка конструкторов с variadic template
template<typename ...Ts>
class Test
{
private:
std::tuple<Ts...> _tpl;
public:
Test() : _tpl{ std::tuple{Ts{}... } } {} //ctor1
Test(Ts... ob) : _tpl { std::tuple{ob... } } {} // ctor2
};
int main()
{
Test<int, float> a; // ctor1 ok
Test b{10, 2.5}; // ctor2 ok
//Test<> c{}; // compile error
return 0;
}
Как сделать так, чтобы можно было создавать объект класса Test с нулевым числом параметров? При этом оба существующих конструктора нужно оставить.
Ответы (2 шт):
Автор решения: HolyBlackCat
→ Ссылка
Вот так:
Test() : _tpl{ std::tuple{Ts{}... } } {} //ctor1
Test(Ts... ob) requires(sizeof...(Ts) > 0) : _tpl { std::tuple{ob... } } {} // ctor2
Но лучше вот так:
Test() {}
Test(Ts... ob) requires(sizeof...(Ts) > 0) : _tpl(std::move(ob)...) {}
И передачу по универсальной ссылке тоже.
Выбирайте. Раз:
template <typename ...P>
class Test
{
private:
std::tuple<P...> _tpl;
public:
template <typename ...Q>
Test(Q &&... params) : _tpl(std::forward<Q>(params)...) {}
};
template <typename ...P> Test(P &&...) -> Test<std::decay_t<P>...>;
Два:
template <typename ...P>
class Test
{
private:
std::tuple<std::decay_t<P>...> _tpl;
public:
Test() {}
Test(P &&... params) : _tpl(std::forward<P>(params)...) {}
};
template <typename ...P> Test(P &&...) -> Test<P...>;
Автор решения: Алексей Ларин
→ Ссылка
Решение. Дополнительно, учитывает передачу параметров как lvalue. Спасибо HolyBlackCat! 15 минут назад
template<typename ...Ts>
class Test
{
private:
std::tuple<Ts...> _tpl;
public:
Test() {}
Test(Ts &&...ob) requires(sizeof...(Ts) > 0) : _tpl(std::move(ob)...) {}
Test(Ts &...ob) requires(sizeof...(Ts) > 0) : _tpl(std::forward<Ts>(ob)...) {}
};
int main()
{
Test<int, float> a; // ctor1 ok
Test b{10, 2.5}; // ctor2 ok
Test c; // ctor1
int i;
float f;
Test d{i, f}; // ctor3 ok
return 0;
}