繁体   English   中英

std::array 初始化,对于没有默认构造函数的对象?

[英]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,但也许这可能会有所帮助?

选项 1:使用命名构造函数习惯用法

我们将编写一个命名的构造函数 idiomarray_repeat() ,它接受一个值并在编译时生成一个包含所有值的数组。 然后你可以写:

class Foo {
public:
  Foo() : fooArr {array_repeat<arr_size>(Bar(ctor_arg))} {}
private:
  std::array<Bar, arr_size> fooArr;
};

我已经将实现分成了一个单独的问题和答案,这里是 SO

选项 2:使用带有自定义分配器的向量

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM