Вы можете сделать так, чтобы ваши конструкторы принимали ссылки на массивы:
struct foo {
foo(const double (&A)[3]) {}
foo(const double (&A)[4]) {}
};
И если функции достаточно похожи, вы можете сделать шаблон, принимающий обе версии:
struct foo {
template<size_t N, std::enable_if_t<N == 3 || N == 4, bool> = true>
constexpr foo(const double (&A)[N]) noexcept {
std::copy(std::begin(A), std::end(A), values);
if constexpr(N == 3) values[3] = ... // some constant;
}
double values[4];
};
Есливам нужно принять динамически размещенные массивы (double*
) с размерами, известными во время компиляции, вы можете создать шаблон конструктора, используя теги, чтобы утверждать, что используемые размеры приемлемы.
struct foo {
template<size_t N, std::enable_if_t<N == 3 || N == 4, bool> = true>
struct size_tag_t {};
// convenience tag instances
static constexpr size_tag_t<3> three_tag{};
static constexpr size_tag_t<4> four_tag{};
template<size_t N>
constexpr foo(const double* A, size_tag_t<N>) noexcept {
std::copy(A, A + N, values);
if constexpr(N == 3) values[3] = ... // some constant;
}
double values[4];
};
//...
constexpr size_t THREE = 3;
double* da3 = new double[THREE];
foo pthree1(da3, foo::size_tag_t<THREE>{});
// or
foo pthree2(da3, foo::three_tag);