I need to initialize a compile-time sized class array with an initializer_list. I'm already aware that I could use a parameter pack constructor and initialize it on the spot, but I need to use an initializer_list in this case. I'd also like to avoid dynamically initializing the array if possible. Here's the pseudo-code:
template<typename Type, std::size_t Length>
class Test
{
public:
Test(const std::initializer_list<Type> args)
: m_tData(args) //<-- Doesn't work of course
{}
private:
Type m_tData[Length];
};
Of course, for non-const types, I could do
Test(const std::initializer_list<Type> args)
{
std::copy(args.start(), args.end(), m_tData);
}
but this doesn't work if I try to use a const class like Test<const int, 3>({1, 2, 3})
. Am I forced to use template specialization to have the internal array not actually be const so I can initialize it from the constructor body?
I'm using C++20. I've seen How do I initialize a member array with an initializer_list? but was wondering if anything has changed since then.
Possible solution:
template<typename Type, std::size_t Length>
class Test
{
public:
Test(std::initializer_list<Type> args) :
Test(args, std::make_index_sequence<Length>{})
{
assert(args.size() == Length);
}
private:
template<std::size_t... ii>
Test(std::initializer_list<Type> args, std::index_sequence<ii...>) :
m_tData{(*(args.begin() + ii))...}
{}
Type m_tData[Length];
};
https://godbolt.org/z/d8Zg3q
Is there a way I could still support initializer_lists of lesser lengths than the templated length? Say something like
Test<const int, 5>({1, 2, 3})
?
If the remaining elements are supposed to be initialized with Type{}
, just a slight modification is needed:
Test(std::initializer_list<Type> args) :
Test(args, std::make_index_sequence<Length>{})
{
assert(args.size() <= Length);
}
template<std::size_t... ii>
Test(std::initializer_list<Type> args, std::index_sequence<ii...>) :
m_tData{(ii < args.size() ? *(args.begin() + ii) : Type{})...}
{}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With