Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can member functions be used to initialize member variables in an initialization list?

OK, member variables can be used to initialize other member variables in an initialization list (with care taken about the initialization order etc). What about member functions? To be specific, is this snippet legal according to the C++ standard?

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 }; 
like image 879
ev-br Avatar asked Jun 24 '12 00:06

ev-br


People also ask

How do you initialize a member variable?

To initialize a class member variable, put the initialization code in a static initialization block, as the following section shows. To initialize an instance member variable, put the initialization code in a constructor.

What is a member initializer list?

Member initializer list is the place where non-default initialization of these objects can be specified. For bases and non-static data members that cannot be default-initialized, such as members of reference and const-qualified types, member initializers must be specified.

What is member initialization?

It probably refers to in-class member initializers. This allows you to initialize non-static data members at the point of declaration: struct Foo { explicit Foo(int i) : i(i) {} // x is initialized to 3.1416 int i = 42; double x = 3.1416; }; More on that in Bjarne Stroustrup's C++11 FAQ.

How do you initialize a data member in C++?

Static Data Member Initialization in C++ We can put static members (Functions or Variables) in C++ classes. For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator, then the variable name.


1 Answers

Yes, your use of member function in initialization list is valid and complies with the standard.

Data members are initialized in the order of their declaration (and that's the reason why they should appear in the initialization list in the order of their declaration - the rule that you followed in your example). N_ is initialized first and you could have passed this data member to fill_arr. fill_arr is called before constructor but because this function does not access uninitialized data members (it does not access data members at all) its call is considered safe.

Here are some relevant excepts from the latest draft (N3242=11-0012) of the C++ standard:

§ 12.6.2.13: Member functions (including virtual member functions, 10.3) can be called for an object under construction.(...) However, if these operations are performed in a ctor-initializer (or in a function called directly or indirectly from a ctor-initializer) before all the mem-initializers for base classes have completed, the result of the operation is undefined. Example:

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

§12.7.1: For an object with a non-trivial constructor, referring to any non-static member or base class of the object before the constructor begins execution results in undefined behavior. Example

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    } }; 
like image 179
Bojan Komazec Avatar answered Sep 19 '22 14:09

Bojan Komazec