采用不同大小数组的构造函数

Constructors that take different sizes of arrays

本文关键字:数组 构造函数 小数      更新时间:2023-10-16

我可以这样做:

struct foo{
foo(std::array<double, 3>){}
foo(std::array<double, 4>){}
}

我想这样做:

struct foo{
foo(double A[3]){}
foo(double A[4]){}
}

当然,这是行不通的。

这涉及具有大量 3 和 4 元素双精度数组的遗留代码。 我希望构造一个包含来自 3 或 4 个元素数组的 4 个双精度值的类,并在从 3 元素数组构造时用常量值初始化第 4 个双精度值。 当我从 4 元素数组初始化时,我只是复制 4 个元素。

所以,我想让构造函数识别:

double something[3];

从:

double something_else[4];

我能想到的最好的方法是向构造函数添加另一个参数以区分两者。

class foo{
foo(double A[4], bool only_3 = false){}
foo(double *A, size_t n = 4){}
}

有什么更好的主意吗?

(如果时间允许,我会赶出所有的原始数组,但现在我必须处理它。

数组可以通过引用传递。 如果你有

struct foo{
foo(double (&A)[3]){}
foo(double (&A)[4]){}
};

然后foo只能由大小为 3 或大小为 4 的数组构造。 这确实会阻止您接受指针,因此

double bar = new double[4];
foo f(bar);

行不通。

你可以让你的构造函数接受对数组的引用:

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);