在构造函数中初始化 std::array 成员?

Initilise std::array member in constructor?

提问人:JHeni 提问时间:11/9/2023 最后编辑:Remy LebeauJHeni 更新时间:11/9/2023 访问量:95

问:

我正在寻找一种初始化成员的方法。std::array

构造函数定义数组的大小。此大小在编译时是已知的。

显然,我可以通过模板参数传递数组的大小。

#include <array>

template<size_t x, size_t y>
class MyClass
{
public:
  void memberFunction1();
  void memberFunction2();
  std::array<uint8_t, x*y> m_array;
};

但是,这里的问题是,我需要在所有成员函数中携带模板参数(这使得事情更难阅读)。

有没有办法在/构造函数中初始化数组?所以像这样的东西(虽然我无法让它工作):constexprconsteval

#include <array>

class MyClass
{
public:
  std::array m_arr;

  explicit consteval MyClass(const size_t x, const size_t y):
    m_arr{uint8_t, x*y}
  {    
  }
};

我没有选择或其他东西,因为我想避免动态内存分配。std::vector

C++ 数组

评论

1赞 Ben Voigt 11/9/2023
无法避免将参数放在整个类上,因为它们会影响类的内存布局。
0赞 NathanOliver 11/9/2023
您可以使用模板,或者支付动态分配的成本。数组大小在编译时必须已知,并且函数参数不是编译时常量。Double 因此,作为类成员,必须在不了解构造函数的情况下定义其大小
0赞 Ben Voigt 11/9/2023
@NathanOliver:当函数为 时,它们(在调用的上下文中)是 。但这对 OP 来说并不重要。也无法将函数的模板参数(肯定是编译时常量)转换为数据成员的模板参数。consteval
0赞 Artyer 11/9/2023
@BenVoigt(函数参数从来都不是常量表达式。即使对于函数,它们也不会被强制为调用站点的常量表达式: godbolt.org/z/b8sW3hh7q ) 另请参阅 此问题不能具有与以下不同的类型: stackoverflow.com/a/56131346(您需要尚未添加到C++的参数)constevalMyClass(1, 2)MyClass(2, 3)constexpr
0赞 Ben Voigt 11/9/2023
@Artyer:它们必须在第一个调用方的上下文中保持不变,而不是在被调用方(或调用图的中间函数)中。我的第一条评论解释了为什么参数值需要成为类类型的一部分,因此类模板参数也需要成为类的一部分。

答:

1赞 Red.Wave 11/9/2023 #1

您可以使用 CTAD,但首先需要一些准备工作:

template<std::size_t x, std::size_t y>
struct dims{
    constexpr static std::integral_constant<std::size_t, x> width;
    constexpr static std::integral_constant<std::size_t, y> height;
}; //dims

接下来,我们可以使用类的构造函数参数:dims

template<std::size_t x, std::size_t y>
class my_class{
public:
    constexpr static dims<x,y> size;
    constexpr my_class(dims<x,y>)/*ctor definition*/;
private:
    /*rest of my_class*/
};

现在 C++20 为我们提供了默认的 CTAD 机制:

my_class my_object{ dims<my_x,my_y>{} };

请注意,对于 CTAD,所有模板参数都必须可从构造函数参数中推导出来。在这个例子中,我们只有维度参数。如果类模板列表中有其他参数,它们也必须以某种方式反映在构造函数参数中。 在 C++17 中,你需要一个 CTAD 指令:

template<std::size_t x, std::size_t y>
myclass(dims<x,y>) -> my_class<x,y>;

评论

1赞 user4581301 11/9/2023
术语:CTAD
0赞 Red.Wave 11/9/2023
构造函数模板参数推导。
1赞 JHeni 11/9/2023
谢谢你的答案。我会尝试使用CTAD:)