[英]std::array initialization, for objects without a default ctor?
我在一个内存受限的系统上工作,其中 new/malloc 调用被包装为在构建时失败。 因此,不幸的是, std::vector
不是一个可接受的解决方案。
我有一个类的std::array
成员,其中的大小在编译时已知,但可能因特定目标(例如来自配置文件)而异,因此我可以访问诸如constexpr size_t len = Config::ArrSize
。 我希望我的类保存一个std::array
对象,但这些对象没有默认构造函数。 我更愿意避免两步初始化(例如,实现一个无意义的默认构造函数,然后稍后将实际值传递给它们)。 我也知道编译时所有的构造函数值! 我只是找不到一种干净的方式来传达这一点,因为特定目标之间的长度可能会有所不同,但对于任何给定的garget 都是已知的。
有没有办法清楚地传达这一点? 例如,我想要类似的东西
#include Config.h
constexpr size_t arr_size = Config::ArrSize;
constexpr size_t ctor_arg = Config::Arg;
class Foo {
public:
// line which doesn't work but demonstrates what I'd like
Foo() : fooArr {Bar(ctor_arg)} {}
private:
std::array<Bar, arr_size> fooArr;
};
它们都将以相同的方式初始化,并在编译时具有已知的大小。 由于缺少默认构造函数,它们必须在初始化时构造。 类似于std::fill
但在初始化时可用。 是的,我可以用指针将它推迟到 ctor 主体,但这很难看,恕我直言。 我怎样才能做到这一点?
Bar
没有constexper
ctor,但也许这可能会有所帮助?
我们将编写一个命名的构造函数 idiom , array_repeat()
,它接受一个值并在编译时生成一个包含所有值的数组。 然后你可以写:
class Foo {
public:
Foo() : fooArr {array_repeat<arr_size>(Bar(ctor_arg))} {}
private:
std::array<Bar, arr_size> fooArr;
};
我已经将实现分成了一个单独的问题和答案,这里是 SO 。
std::vector
有一个额外的模板参数——分配器类。 默认值是一个使用new[]
和delete[]
的分配器。 但是 - 您可以有一个分配器,它占用堆栈(或任何地方)上的固定缓冲区,并仍然使用可调整大小的std::vector
。 这将使您无需预先构建虚拟值。
你可以这样做:
class Bar
{
public:
Bar(someClass obj) { /*...*/ }
};
class Foo
{
public:
template<class... T>
Foo(T... obj) : fooArr {Bar(obj)...} {}
private:
std::array<Bar, arr_size> fooArr;
}
虽然我不知道这是否是最好的方法。
您可以使用大括号初始化std::array<int,4> a = {1,2,3,4};
...也许您可以编写一个模板函数来初始化它,而无需直接编写初始化列表,但我不确定如何。
通常,当类型不可默认构造时,我不建议使用std::array
。 您可以使用类似boost::small_vector
类型来代替具有静态容量和动态大小的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.