c++ 如何在成员初始值设定项列表中初始化数组成员

gblwokeq  于 2023-10-21  发布在  其他
关注(0)|答案(7)|浏览(114)
class C 
{
public:
 C() : arr({1,2,3}) //doesn't compile
{}
    /*
    C() : arr{1,2,3} //doesn't compile either
{}
    */
private:
 int arr[3];
};

我认为原因是数组只能用=语法初始化,即:

int arr[3] = {1,3,4};

常见问题

1.我怎么能做我想做的事情(也就是说,在构造函数中 * 初始化 * 一个数组(不在主体中分配元素))。这可能吗

  1. C++03标准对在ctor初始化器中初始化聚合(包括数组)有什么特别的规定吗?或者上述代码的无效性是其他一些规则的必然结果?
  2. C++11列表初始化能解决这个问题吗?
    请注意,我不想使用std::array或其他容器来解决这个问题。
h7wcgrx3

h7wcgrx31#

1.我如何做我想做的事情(即在构造函数中初始化数组(而不是在主体中分配元素))。这可能吗
是的。它使用了一个包含数组的结构体。你说你已经知道了,但我不明白这个问题。这样,你就可以在构造函数中初始化一个数组,而不需要在主体中赋值。这就是boost::array所做的。
C++03标准对在ctor初始化器中初始化聚合(包括数组)有什么特别的规定吗?或者上述代码的无效性是其他一些规则的必然结果?
内存初始化器使用直接初始化。第八条的规定禁止这种行为。我不太确定下面的情况,但有些编译器确实允许它。

struct A {
  char foo[6];
  A():foo("hello") { } /* valid? */
};

请参阅this GCC PR了解更多详细信息。
C++0x初始化列表解决了这个问题吗?
是的,他们有。但是你的语法是无效的,我认为。必须直接使用大括号来启动列表初始化

struct A {
  int foo[3];
  A():foo{1, 2, 3} { }
  A():foo({1, 2, 3}) { } /* invalid */
};
7vhp5slm

7vhp5slm2#

C98除了对数组进行置零(或对非POD元素进行值初始化)之外,没有提供任何直接的语法。所以你只需要写C(): arr() {}
我认为Roger Pate关于C
0x聚合初始化的所谓限制是错误的,但我懒得去查它或检查它,这并不重要,不是吗?编辑:罗杰说的是“C03”,我把它误读为“C0x”。抱歉罗杰☺
当前代码的C++98解决方法是将数组 Package 在struct中,并从该类型的静态常量初始化它。无论如何,数据必须驻留在某个地方。它可以看起来像这样:

class C 
{
public:
    C() : arr( arrData ) {}

private:
     struct Arr{ int elem[3]; };
     Arr arr;
     static Arr const arrData;
};

C::Arr const C::arrData = {{1, 2, 3}};
ldfqzlk8

ldfqzlk83#

解决方法:

template<class T, size_t N>
struct simple_array { // like std::array in C++0x
   T arr[N];
};

class C : private simple_array<int, 3> 
{
      static simple_array<int, 3> myarr() {
           simple_array<int, 3> arr = {1,2,3};
           return arr;
      }
public:
      C() : simple_array<int, 3>(myarr()) {}
};
7lrncoxx

7lrncoxx4#

1.不,很不幸。
1.你只是不能以你想要的方式,因为它是不允许的语法(更多下面)。您只能使用类似ctor的初始化,并且,如您所知,这不适用于初始化数组中的每个项。
1.我相信是这样的,因为它们以许多有用的方式全面地概括了初始化。但我不确定细节。
在C++03中,聚合初始化只适用于类似于下面的语法,它必须是一个单独的语句,并且不适合于ctor初始化器。

T var = {...};
l7mqbcuq

l7mqbcuq5#

我发现这个问题非常有用,但是没有发现成员数组元素是一个没有默认构造函数和删除了复制/移动构造函数的对象的例子。换句话说,这个例子在没有不必要的对象复制的情况下复制了成员数组。
例如,对于下面的class A:

class A {
  public:
    int v;
    A(int v) : v(v) { }
    A() = delete;
    A(A &&) = delete;
    A(const A &) = delete;
    A &operator =(A &&) = delete;
    A &operator =(const A &) = delete;
};

使用非默认构造函数的就地初始化如下所示:

class B {
  public:
    A a[3];
    B() : a { {1}, {2}, {3} } {}
};
qv7cva1a

qv7cva1a6#

怎么样

...
  C() : arr{ {1,2,3} }
{}
...


在g++ 4.8上编译良好

ej83mcc0

ej83mcc07#

这对我在Windows上使用C++17很有效:
文件A.h

class A
{
  private:
    float arrayVar[3];
}

文件A.cpp

A::A() : arrayVar{ 0.0f, 0.0f, 0.0f } { }

相关问题