can成员函数可用于初始化初始化列表中的成员变量吗?

ev-*_*-br 34 c++ initialization-list

好的,成员变量可用于初始化初始化列表中的其他成员变量(注意初始化顺序等).会员职能怎么样?具体来说,这个片段是否符合C++标准?

struct foo{
  foo(const size_t N) : N_(N),  arr_(fill_arr(N)) { 
    //arr_ = fill_arr(N); // or should I fall back to this one?
  }

  std::vector<double> fill_arr(const size_t N){
    std::vector<double> arr(N);
    // fill in the vector somehow
    return arr;
  }

  size_t N_;
  std::vector<double> arr_;
  // other stuff
};
Run Code Online (Sandbox Code Playgroud)

Boj*_*zec 37

是的,您在初始化列表中使用成员函数是有效的并且符合标准.

数据成员按其声明的顺序进行初始化(这就是为什么它们应按声明顺序出现在初始化列表中的原因 - 您在示例中遵循的规则).N_首先进行初始化,您可以将此数据成员传递给fill_arr.fill_arr在构造函数之前调用,但因为此函数不访问未初始化的数据成员(它根本不访问数据成员),所以它的调用被认为是安全的.

以下是C++标准最新草案(N3242 = 11-0012)的一些相关例外:

§12.6.2.13:可以为正在构造的对象调用成员函数(包括虚拟成员函数,10.3).(...)但是,如果这些操作是在ctor-initializer(或直接或间接调用的函数)中执行的在完成基类的所有mem-initializer之前,从ctor-initializer开始,操作的结果是未定义的.例:

class A { public:    A(int); };

class B : public A {
   int j;
public:
   int f();
   B() : A(f()), // undefined: calls member function
                 // but base A not yet initialized
   j(f()) { }    // well-defined: bases are all initialized
};

class C {
public:
   C(int);
};

class D : public B, C {
   int i;
public:
   D() : C(f()), // undefined: calls member function
                 // but base C not yet initialized
   i(f()) { } // well-defined: bases are all initialized
};
Run Code Online (Sandbox Code Playgroud)

§12.7.1:对于具有非平凡构造函数的对象,在构造函数开始执行之前引用对象的任何非静态成员或基类会导致未定义的行为.例

struct W { int j; };
struct X : public virtual W { };
struct Y {
   int *p;
   X x;
   Y() : p(&x.j) { // undefined, x is not yet constructed
   }
};
Run Code Online (Sandbox Code Playgroud)


Eig*_*ght 6

在初始化列表中初始化对象时,该对象尚未完全构造.
如果这些函数试图访问尚未构造的对象部分,那么这是一个未定义的行为,否则就可以了.
看到这个答案.