如何通过构造函数调整私有 std::array 成员的大小?

Posted

技术标签:

【中文标题】如何通过构造函数调整私有 std::array 成员的大小?【英文标题】:How can I size a private std::array member through the constructor? 【发布时间】:2019-07-09 02:05:15 【问题描述】:

我有一个class B,它应该包含一个private std::array<A*>,并且大小将通过构造函数发送

class B

  public:
    B(size_t s) : vv(s,nullptr), aa(s) 
    // ... more stuff
  private:
    std::vector<A*>   vv;   // vector works fine
    std::array<A*,??> aa;   // but how to initialize an array??

使用std::vector 可以正常工作,但我似乎无法使用std::array

添加另一个成员 const size_t ss 并在 std::array 声明中使用它也不起作用,即使它是 static const size_t ss - 编译器(VS2019 16.1.5,设置为 C++17)声称“ ...预期的编译时常量..."

class B  // another try with a static const size_t

  public:
    B(size_t s) : ss(s), aa(s) 
    // ... more stuff
  private:
    static const size_t ss;
    std::array<A*,ss> aa;   // no, ...expected compile-time constant...

该消息似乎暗示没有办法 - 如果需要在编译时知道大小,则它需要相同 对于类的所有实例/对象 - 这与我的计划直接相矛盾。

当然,我可以做一个模板类,或者我可以直接留在std::vector;或者我可以使用一种“PIMPL”(声明一个指向该数组的指针,并在构造函数中使用new 创建它)——这不是问题。

问题是:我可以在构造函数中传递待定数组的大小,然后直接从中创建它吗? 有什么花哨的结构或技巧吗?

[注意:不是 Initializing private std::array member in the constructor、Initializing std::array private member through constructor 或 How to construct std::array object with initializer list? 的副本 - 我不想传递 ,但是 数组大小]

【问题讨论】:

为什么不想使用向量? std::array 的大小必须知道并在编译时指定。构造函数接收到的内容直到运行时才知道。您不能以这种方式使用std::array,C++ 根本无法以这种方式工作。 vector 工作正常,当然。我想知道我是否可以在这种情况下使用array。我知道没有或无限小的性能或内存增益 - 这纯粹是教育 嗯,你刚刚接受了教育,说你不能在这种情况下使用std::array。这不是它的用途。 谢谢。通过简单地编写问题,它已经变得更加清晰了——但经过努力,我不想把它全部扔掉。它也可以帮助其他人。 【参考方案1】:

你不能。 std::array 的大小是在编译时确定的,而不是在运行时确定的。对于运行时存储,使用 std::vector。与类最接近的方法是将类声明为模板,如下所示:

template<size_t size>
class Foo 
   std::array<size> member;
;

但如果你想将大小作为 arg 传递给构造函数,则需要使用 std::vector。

【讨论】:

【参考方案2】:

您可以“假装”将大小传递给构造函数。

template <size_t Size>
struct array_size_t ;

template <size_t Size>
constexpr array_size_t<Size> array_size ;

template <size_t Size>
class Foo 
public:
  explicit Foo(array_size_t<Size>) 

private:
  std::array<int, Size> arr;
;

Foo fooarray_size<12>;

不知道为什么要使用此代码,因为Foo&lt;12&gt; foo;Foo fooarray_size&lt;12&gt;; 短得多。

【讨论】:

以上是关于如何通过构造函数调整私有 std::array 成员的大小?的主要内容,如果未能解决你的问题,请参考以下文章

初始化具有非默认构造函数的 std::array 项的更好方法?

如何使用初始化列表构造 std::array 对象? [复制]

编译器生成的默认构造函数是否会将std :: array中的指针初始化为nullptr?

java构造函数私有化

初始化非默认可构造元素的 std::array?

如何通过可变参数模板将多个构造函数参数转发到数组初始值设定项列表?