C++ 在构造函数初始值设定项中初始化成员数组

C++ 在构造函数初始值设定项中初始化成员数组,c++,c++11,initializer-list,ctor-initializer,aggregate-initialization,C++,C++11,Initializer List,Ctor Initializer,Aggregate Initialization,我认为原因是数组只能用=语法初始化,即: class C { public: C() : arr({1,2,3}) //doesn't compile {} /* C() : arr{1,2,3} //doesn't compile either {} */ private: int arr[3]; }; 问题 我怎样才能做我想做的事 是,初始化 构造函数(不指定元素) 在体内)。有可能吗 C++03标准对在ctor初始化器中初始化聚合(包括数组)有什么特别的规定

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

class C 
{
public:
 C() : arr({1,2,3}) //doesn't compile
{}
    /*
    C() : arr{1,2,3} //doesn't compile either
{}
    */
private:
 int arr[3];
};
问题
  • 我怎样才能做我想做的事 是,初始化 构造函数(不指定元素) 在体内)。有可能吗
  • C++03标准对在ctor初始化器中初始化聚合(包括数组)有什么特别的规定吗?或者上述代码的无效性是其他一些规则的必然结果
  • C++0x初始值设定项列表解决了这个问题吗
  • p.S.请不要提及向量、boost::数组及其相对于数组的优势,我很清楚这一点

  • 不,很遗憾
  • 你不能按照你想要的方式去做,因为语法是不允许的(详见下文)。您只能使用类似于ctor的初始化,而且正如您所知,这不适用于初始化数组中的每个项
  • 我相信是这样,因为它们以许多有用的方式全面概括了初始化。但我不确定细节
  • 在C++03中,聚合初始化只应用与下面类似的语法,它必须是一个单独的语句,并且不适合于ctor初始值设定项

    int arr[3] = {1,3,4};
    
    解决方法:

    T var = {...};
    
    模板
    结构简单数组{//类似于C++0x中的std::array
    T arr[N];
    };
    C类:私有简单数组
    {
    静态简单数组myarr(){
    简单_数组arr={1,2,3};
    返回arr;
    }
    公众:
    C():简单数组(myarr()){
    };
    
    C++98只为数组的归零(或非POD元素的值初始化)提供直接语法。为此,您只需编写
    C():arr(){}

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

    当前代码的一个C++98解决方案是将数组包装在
    结构中
    并从该类型的静态常量初始化它。无论如何,数据必须驻留在某个地方。即兴表演可以是这样的:

    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()) {}
    };
    
  • 如何做我想做的事情(即,在构造函数中初始化数组(而不是在主体中分配元素))。有可能吗 对。它使用一个包含数组的结构。你说你已经知道了,但我不明白这个问题。这样,就可以在构造函数中初始化数组,而不用在主体中赋值。这就是
    boost::array
    所做的

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

    mem初始值设定项使用直接初始化。第8条的规定禁止这种事情。我不完全确定下面的情况,但有些编译器确实允许这样做

    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++0x初始值设定项列表解决了这个问题吗

    是的,有。然而,我认为你的语法是无效的。您必须直接使用大括号来启动列表初始化

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

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


    在g++4.8上编译得很好

    是否要在构造函数中初始化int数组?将它指向一个静态数组

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

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

    例如,对于以下a类:

    class C 
    {
    public:
        int *cArray;
    
    };
    
    C::C {
        static int c_init[]{1,2,3};
        cArray = c_init;
    }
    
    使用非默认构造函数的就地初始化如下所示:

    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;
    };
    

    您是否也知道boost固定大小数组的存在,它们提供构造函数?@Benoît:我知道。但我需要知道普通数组:)我说0x有什么限制?@Roger:“agregate初始化…不适合于ctor初始化器”。只要检查一下C++0x草案N3126,§12.5.2/1中mem初始值设定项的语法,就包括使用大括号的init-list。我句子的前两个单词是C++03,…这是标准吗?你能引用相关的条款吗?不在VisualC++中编译。这是个坏主意,因为如果你改变了这个数组,它就被改变了,因为我写的是:<代码> char * const fo(6);<代码>类成员。它需要初始值设定项在C++11中编译。
    class B {
      public:
        A a[3];
        B() : a { {1}, {2}, {3} } {}
    };