C++ 成员函数能否用于初始化初始化列表中的成员变量?

C++ 成员函数能否用于初始化初始化列表中的成员变量?,c++,initialization-list,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

好的,使用成员变量初始化初始化列表中的其他成员变量(注意初始化顺序等)。成员功能如何?具体地说,这个代码段是按照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
};
structfoo{
foo(常量大小):N(N),arr(填充arr(N)){
//还是我应该回到这个问题上来?
}
标准::矢量填充(常数大小){
std::向量arr(N);
//以某种方式填充向量
返回arr;
}
大小;
std::向量arr;
//其他东西
};

初始化初始化列表中的对象时,对象尚未完全构造。
如果这些函数试图访问对象中尚未构造的部分,则这是未定义的行为,否则没有问题。

请参阅。

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

数据成员按照其声明的顺序进行初始化(这就是为什么它们应该按照声明的顺序出现在初始化列表中的原因—您在示例中遵循的规则)<代码>N首先初始化,您可以将此数据成员传递给
fill\u arr
fill\u arr
在构造函数之前被调用,但由于此函数不访问未初始化的数据成员(它根本不访问数据成员),因此其调用被认为是安全的

这里是C++标准中最新草案(N3242= 11-012)中的一些相关例外:

§12.6.2.13:成员功能(包括虚拟成员功能, 10.3)可以为正在构造的对象调用。(…)但是,如果这些操作是在ctor初始值设定项(或函数)中执行的 在所有 基类的mem初始值设定项已经完成,结果是 操作未定义。例如:

§12.7.1:对于具有非平凡构造函数的对象,参考 前对象的任何非静态成员或基类 构造函数开始执行导致未定义的行为。范例


这正是问题的核心:成员函数的构造顺序规则是什么?如果我错了,请纠正我:您所指的问题涉及的是成员变量,而不是成员函数。您是否暗示成员函数遵循相同的规则?首先,gcc 4.4.3不会抱怨我是否切换了
arr\u
fill\u arr()
的声明顺序,但如果init列表中的顺序与声明顺序不同,它会发出警告。@Zhenya sbi答案()的第一部分是针对成员函数的。好吧,他对答案也有评论。。。(+1表示链接。)问题很好,但代码示例有点人为。是什么阻止您将
fill\u arr
声明为
static
,并且毫无疑问它是合法的?这是线程安全的吗?我的意思是,
fill\u arr
有一个本地向量,如果这是
静态的
,我是不是要用一种互斥锁来保护它?
std::vector arr
有自动存储,所以每次调用函数
fill\u arr
都会有一个实例。这是基本的C++…在这个例子中最好把fILILARR标记为const。为了可读性。
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
};
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
   }
};