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

发布于 2024-09-30 01:45:28 字数 502 浏览 3 评论 0原文

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. 我怎样才能做我想做的事(即 就是初始化 a 中的一个数组 构造函数(不分配元素 在体内))。有可能吗?
  2. C++03 标准是否对构造函数初始值设定项中的初始化聚合(包括数组)有任何特殊说明?或者上述代码的无效性是其他一些规则的必然结果?
  3. C++11列表初始化解决了这个问题吗?

请注意,我不想使用 std::array 或其他容器来解决此问题。

class C 
{
public:
 C() : arr({1,2,3}) //doesn't compile
{}
    /*
    C() : arr{1,2,3} //doesn't compile either
{}
    */
private:
 int arr[3];
};

I believe the reason is that arrays can be initialized only with = syntax, that is:

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

Questions

  1. How can I do what I want to do (that
    is, initialize an array in a
    constructor (not assigning elements
    in the body)). Is it even possible?
  2. Does the C++03 standard say anything special about initializing aggregates (including arrays) in ctor initializers? Or the invalidness of the above code is a corollary of some other rules?
  3. Does C++11 list initialization solve the problem?

Note that I do not want to use std::array or another container to solve this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

谁把谁当真 2024-10-07 01:45:28
  1. 我怎样才能做我想做的事(即在构造函数中初始化数组(而不是在主体中分配元素))。有可能吗?

是的。它使用包含数组的结构。你说你已经知道了,但我不明白这个问题。这样,您就可以在构造函数中初始化数组,而无需在主体中进行赋值。这就是 boost::array 的作用。

C++03 标准对于在构造函数初始化器中初始化聚合(包括数组)有什么特别规定吗?或者上述代码的无效性是其他一些规则的必然结果?

内存初始化程序使用直接初始化。而第8条的规则禁止这种事情。我不太确定以下情况,但有些编译器确实允许这样做。

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

有关更多详细信息,请参阅此 GCC PR

C++0x 初始化列表可以解决问题吗?

是的,他们确实这么做了。但是我认为你的语法无效。您必须直接使用大括号来触发列表初始化

struct A {
  int foo[3];
  A():foo{1, 2, 3} { }
  A():foo({1, 2, 3}) { } /* invalid */
};
  1. How can I do what I want to do (that is, initialize an array in a constructor (not assigning elements in the body)). Is it even possible?

Yes. It's using a struct that contains an array. You say you already know about that, but then I don't understand the question. That way, you do initialize an array in the constructor, without assignments in the body. This is what boost::array does.

Does the C++03 standard say anything special about initializing aggregates (including arrays) in ctor initializers? Or the invalidness of the above code is a corollary of some other rules?

A mem-initializer uses direct initialization. And the rules of clause 8 forbid this kind of thing. I'm not exactly sure about the following case, but some compilers do allow it.

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

See this GCC PR for further details.

Do C++0x initializer lists solve the problem?

Yes, they do. However your syntax is invalid, I think. You have to use braces directly to fire off list initialization

struct A {
  int foo[3];
  A():foo{1, 2, 3} { }
  A():foo({1, 2, 3}) { } /* invalid */
};
风吹过旳痕迹 2024-10-07 01:45:28

除了将数组归零(或对于非 POD 元素,值初始化)之外,C++98 不提供任何直接语法。为此,您只需编写C(): arr() {}

我认为 Roger Pate 关于 C++0x 聚合初始化的所谓限制是错误的,但我懒得查找或检查它,但这并不重要,不是吗? 编辑:罗杰正在谈论“C++03”,我将其误读为“C++0x”。对不起,罗杰。 ☺

当前代码的 C++98 解决方法是将数组包装在 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}};

C++98 doesn't provide a direct syntax for anything but zeroing (or for non-POD elements, value-initializing) the array. For that you just write C(): arr() {}.

I thing Roger Pate is wrong about the alleged limitations of C++0x aggregate initialization, but I'm too lazy to look it up or check it out, and it doesn't matter, does it? EDIT: Roger was talking about "C++03", I misread it as "C++0x". Sorry, Roger. ☺

A C++98 workaround for your current code is to wrap the array in a struct and initialize it from a static constant of that type. The data has to reside somewhere anyway. Off the cuff it can look like this:

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}};
浅唱々樱花落 2024-10-07 01:45:28

解决方法:

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()) {}
};

Workaround:

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()) {}
};
意中人 2024-10-07 01:45:28
  1. 不,不幸的是。
  2. 你只是不能以你想要的方式,因为语法不允许(更多内容见下文)。您只能使用类似 ctor 的初始化,并且如您所知,这不适用于初始化数组中的每个项目。
  3. 我相信是这样,因为他们以许多有用的方式全面概括了初始化。但我不确定细节。

在 C++03 中,聚合初始化仅适用于类似于以下的语法,该语法必须是单独的语句,并且不适合构造函数初始值设定项。

T var = {...};
  1. No, unfortunately.
  2. You just can't in the way you want, as it's not allowed by the grammar (more below). You can only use ctor-like initialization, and, as you know, that's not available for initializing each item in arrays.
  3. I believe so, as they generalize initialization across the board in many useful ways. But I'm not sure on the details.

In C++03, aggregate initialization only applies with syntax similar as below, which must be a separate statement and doesn't fit in a ctor initializer.

T var = {...};
叹沉浮 2024-10-07 01:45:28

我发现这个问题非常有用,但没有找到当成员数组元素是没有默认构造函数且删除了复制/移动构造函数的对象时的示例。换句话说,该示例初始化成员数组而无需进行不必要的对象复制。

例如,对于以下类 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} } {}
};

I found this question very useful, but found no example for the case when the member array element is an object without default constructor and with deleted copy/move constructors. In other words the example that initializes the member array without unnecessary object copy.

For example, with a following 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;
};

In-place initialization with non-default constructor would look like:

class B {
  public:
    A a[3];
    B() : a { {1}, {2}, {3} } {}
};
赢得她心 2024-10-07 01:45:28

怎么样

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

在 g++ 4.8 上编译良好

How about

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

?

Compiles fine on g++ 4.8

水溶 2024-10-07 01:45:28

这对我在 Windows 上使用 C++17 有效:

文件 Ah

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

文件 A.cpp

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

This worked for me using C++17 on Windows:

File A.h:

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

File A.cpp:

A::A() : arrayVar{ 0.0f, 0.0f, 0.0f } { }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文