I want to fill an std::array of size N with objects without a standard constructor.
std::array<non_std_con,N> myArray;
(It's std::array<kissfft<float>, 64>
in my case, to be specific)
This results in the error
error: use of deleted function ... standard constructor
Setup
You can fill the array using an intializer list:
std::array<non_std_con,N> myArray{non_std_con{init1,init2},non_std_con{init1,init2},...}
The initializer list needs N objects.
And you can build an array using parameter packs:
template <class... Params>
auto constexpr build_array(Params... params)
{
std::array<non_std_con, sizeof...(params)> myArray= {params...};
return myArray;
}
Question
Is there a way to use this the other way around and build a parameter pack out of a single argument:
std::array<non_std_con,N> buildArray(inti1,init2);
This would build an array of N non_std_con where every object is initialized with {init1,init2}
Thank you for your time
CodePudding user response:
You could write:
#include <array>
#include <utility>
#include <iostream>
namespace detail
{
template <
typename T,
std::size_t ... Is
>
constexpr std::array<T, sizeof...(Is)> create_array(T value, std::index_sequence<Is...>)
{
// cast Is to void to remove the warning: unused value
return {{(static_cast<void>(Is), value)...}};
}
}
template<
typename T,
int N,
typename... CtorAgrs
>
constexpr std::array<T, N> buildArray(CtorAgrs... args)
{
using Array = std::array<T, N>;
return detail::create_array<T>(T{args...}, std::make_index_sequence<N>());
}
struct Foo{
int a, b;
constexpr Foo(int a, int b) : a(a), b(b)
{
}
};
int main() {
constexpr auto array = buildArray<Foo, 10>(1, 2);
for(const auto& f : array){
std::cout << f.a;
std::cout << "\n";
}
}
or with C -20 simply:
template<
typename T,
int N,
typename... CtorAgrs
>
constexpr std::array<T, N> buildArray(CtorAgrs&&... args)
{
auto doBuildArray = [&]<std::size_t ... Is>(std::index_sequence<Is...>)
-> std::array<T, N>
{
// cast Is to void to remove the warning: unused value
return {{(static_cast<void>(Is), T{args...})...}};
};
return doBuildArray(std::make_index_sequence<N>());
}