I have a class Vec<C>
that works as below, and I need to know a way to write the constructor and/or deduction guide such that a braced-enclosed initializer list deduces C
as std::array<T,N>
.
It works with std::vector<T>
of course, since the size doesn't need to be known.
#include <cassert>
#include <iostream>
#include <array>
#include <vector>
#include <concepts>
#include <type_traits>
template<typename T>
concept has_resize = requires(T t)
{
{t.resize(0)};
};
template<typename C>
class Vec
{
C elems;
public:
template<typename IndexType>
requires std::integral<IndexType> && std::is_unsigned_v<IndexType>
auto operator[](IndexType i) const
{
return elems[i];
}
auto size() const { return elems.size(); }
template<typename T>
Vec(std::initializer_list<T> init)//MEMBER INITIALIZER LIST?
{
// WHAT CODE GOES HERE?
}
Vec(auto init)
{
if constexpr (has_resize<decltype(elems)>)
elems.resize(init.size());
for (decltype(init.size()) i = 0; i<init.size() ; i++)
elems[i] = init[i];
}
};
template<typename C>
Vec(C) -> Vec<C>;
//WHAT'S THE CORRECT DEDUCTION GUIDE?
int main()
{
Vec v0({1, 4, 7});
Vec v1(std::array<int,3>{2, 5, 8});
Vec v2(std::vector<double>{3, 6, 9});
}
Edit 1: The idea is not to modify the call Vec v0({1, 4, 7});
or Vec v0{1, 4, 7};
of course.
Edit 2: template<typename T> Vec(const std::initializer_list<T>& vec) -> Vec<std::array<T, vec.size()>>;
doesn't work as shown here: https://godbolt.org/z/b5vno6ff8
Edit 3: The question is related to Template class and automatic deduction but this is useful still since it underlines the usage on deduction guides.
To deduce the length from a brace-enclosed list, you need to use a reference to array. The syntax is kinda weird:
template<class T, std::size_t N>
Vec(T (&&init)[N]) -> Vec<std::array<T, N>>;