Simplify redundant initialization of std :: array when class does not have constexpr constructor

I have a more complex version of the following code:

#include <array>
#include <cmath>

using namespace std;

class Dummy
{
    public:
        Dummy(const double a, const double f)
        {
            //Some complex calculations
        }
};

constexpr double values[] { 0.1, 0.2, 0.3, 0.4 };
constexpr auto N = sizeof(values) / sizeof(values[0]);
static const array<Dummy, N> dummies {Dummy(10 * values[0], M_PI * 0),
                                      Dummy(10 * values[1], M_PI * 1),
                                      Dummy(10 * values[2], M_PI * 2),
                                      Dummy(10 * values[3], M_PI * 3)};

int main()
{
    //Complex use of dummies
    return 0;
}

I would like to simplify the initialization of the array dummiesas it is very redundant. However, I am associated with C ++ 11, and I cannot change the class Dummyto have a constructor constexpr(which would greatly simplify my situation).

I looked at the variable templates, but it doesn’t seem to get around the fact that the constructor is Dummynot constexpr:

template<size_t... Is>
struct _Helper
{
    static constexpr array<Dummy, N> dummies {Dummy(10 * values[Is], M_PI * Is)...}; //Fails to compile because Dummy constructor is not constexpr
};

static const array<Dummy, N> dummies { _Helper<0, 1, 2, 3>::dummies };

Are there other ways to simplify array initialization? valuescan be replaced as literally by any other that can be converted back to double[]at runtime.

+4
2

, make

template <std::size_t ... Is>
std::array<Dummy, sizeof...(Is)> makeDummArr (double const * vals)
 { return { { Dummy(10 * vals[Is], M_PI * Is)... } }; } }

static const std::array<Dummy, N> dummies = makeDummArr<0, 1, 2, 3>(values);

, ++ 11: Is... ( ) , ++ 14... std::make_index_sequence std::index_sequence...

template <std::size_t ... Is>
std::array<Dummy, sizeof...(Is)> makeDummArr
   (double const * vals, std::index_sequence<Is...> const &)
 { return { { Dummy(10 * vals[Is], M_PI * Is)... } }; }


static const std::array<Dummy, N> dummies
   = makeDummArr(values, std::make_index_sequence<4U>{});

( HolyBlackCat ++ 11 std::index_sequence std::make_index_sequence)

+3

, @max66,
0, 1, ..., N-1 .

template <int ...I> struct int_seq // A rip-off of C++14 std::index_sequence.
{
    template <int X> using push_back = int_seq<I..., X>;
};
template <int N> struct make_int_seq_impl
{
    using type = typename make_int_seq_impl<N-1>::type::template push_back<N-1>;
};
template <> struct make_int_seq_impl<0>
{
    using type = int_seq<>;
};
template <int N> using make_int_seq = typename make_int_seq_impl<N>::type;

template <int ...I> array<Dummy, N> make_dummies(int_seq<I...>)
{
    return {Dummy(10 * values[I], M_PI * I)...};
}

static const array<Dummy, N> dummies = make_dummies(make_int_seq<N>{});
+2

Source: https://habr.com/ru/post/1693469/


All Articles