I want to be able to use parameter pack expansion in the initializer list of constructors. Is the best way to achieve this, to endow my class with a parameter pack template argument? Here is an example of what I mean: https://coliru.stacked-crooked.com/a/e699c4cd035e0b1c
#include <utility>
#include <iostream>
template<typename T, std::size_t...Is>
struct base_vec
{
constexpr static std::size_t N = sizeof...(Is);
T e[N];
base_vec() : e{} {}
explicit base_vec(const T& s) : e{((void)Is,s)...} {}
};
template<typename T, std::size_t...Is>
std::ostream& operator<<(std::ostream& lhs, const base_vec<T,Is...>& rhs)
{
return (std::cout << ... << rhs.e[Is]);
}
template<typename T, std::size_t...Is>
constexpr auto getVecIs(std::index_sequence<Is...> seq)
{
return base_vec<T, Is...>{};
}
template<typename T, std::size_t N>
using vec = decltype(getVecIs<T>(std::declval<std::make_index_sequence<N>>()));
int main()
{
vec<int,3> v(2);
std::cout << v << "\n";
return 0;
}
Note the trivial expansion e{((void)Is,s)...}
. Is this an ok practice, or am I missing some minus of this approach (except for the fact that now my structure will have a whole parameter pack, as opposed to a single size_t N
)?
You can move the expansion entirely inside the class:
template<typename T, std::size_t N>
struct vec
{
public:
T e[N];
vec() : e{} {}
explicit vec(const T& s) : vec{s, std::make_index_sequence<N>{}} {}
private:
template <std::size_t ... Is>
vec(const T& s, std::index_sequence<Is...>) : e{(Is, s)...} {}
};