问题
I have a class template which builds a simple array based on the template parameters as one of its members. I need to be able to initialize every element in the array to a single value in one of the constructors. Unfortunately this constructor must be constexpr
.
The relevant part boils down to:
template <typename T, size_t N>
class foo
{
T data[N];
constexpr foo(T val)
{
// initialize data with N copies of val
}
};
Using std::fill
or a loop is incompatible with the constexpr
requirement. Initializing with : data{val}
only sets the first element of the array and zero-initializes the remainder.
How can this be achieved?
I feel like there should be a solution with variadic templates and tuples etc...
回答1:
Rather curiously, a solution for the problem exists in c++14 (compile the example with -std=c++1y
on gcc; also see comments for a bit more verbose c++11 solution by Praetorian):
template <size_t N>
struct bar {
template <typename T, typename ...Tn>
static constexpr auto apply(T v, Tn ...vs)
{
return bar<N - 1>::apply(v, v, vs...);
}
};
template <>
struct bar<1> {
template <typename T, typename ...Tn>
static constexpr auto apply(T v, Tn ...vs)
{
return std::array<T, sizeof...(vs) + 1>{v, vs...};
}
};
template <typename T, size_t N>
struct foo {
std::array<T, N> data;
constexpr foo(T val)
: data(bar<N>::apply(val))
{}
};
(I replaced the POD array with std::array - suppose it should not make any problems for your use case).
Live example is here: http://coliru.stacked-crooked.com/a/4731a10ee54563b9
回答2:
You may use the following: (https://ideone.com/xTacMP)
namespace detail
{
template <typename T, std::size_t...Is>
constexpr std::array<T, sizeof...(Is)> make_array(T val, index_sequence<Is...>)
{
return {(static_cast<void>(Is), val)...};
}
}
template <std::size_t N, typename T>
constexpr std::array<T, N> make_array(T val)
{
return detail::make_array(val, make_index_sequence<N>());
}
And then call it:
constexpr foo(T val) : data(make_array<N>(val)) {}
来源:https://stackoverflow.com/questions/23901394/c11-initialize-array-with-uniform-value-in-constexpr-function