2

Can I safely use members to initialize others?

class Class {
 public:
  Class(X argument) : memberA(argument), memberB(memberA) {}

  A memberA;
  B memberB;
};

Here we use the argument to the constructor to initialize memberA. We then rely on the fact that this happens before the initialization of memberB and initialize memberB using memberA.

If we assume X, A, and B to be std::string the above example works (tested with gcc), as long as we do not change the order in which the members are declared. But is this actually guaranteed by the standard or am I abusing an implementation detail of the compiler?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Seriously
  • 884
  • 1
  • 11
  • 25
  • 3
    This is perfectly fine and legal, as long as you pay attention to the initialization order. Members are initialized in the order they are declared in the class, not in the order they appear in the initialization list – Remy Lebeau Jan 21 '22 at 17:15
  • @NicolBolas That target is not correct, it only covers the order of initialization of members, not whether members can be used in the initialization of other members. – cigien Jan 21 '22 at 18:14
  • @cigien: If an object is initialized, then its lifetime has started, and therefore it can be used. – Nicol Bolas Jan 21 '22 at 18:15
  • @NicolBolas Yes, I understand that, but the duplicate target doesn't cover that at all. There may well be a duplicate of this question out there, but the current target is not a duplicate. – cigien Jan 21 '22 at 18:16

1 Answers1

1

Yes, this is safe as per class.base.init#15

The expression-list or braced-init-list of a mem-initializer is in the function parameter scope of the constructor and can use this to refer to the object being initialized.

This Note also has an example with this->i to show that previously initialized class members can be used to initialize other class members inside a mem-initializer. (The this-> is only necessary in this example to disambiguate the member and the constructor parameter, both named i).

Be careful that the member is already initialized before using it, since from class.base.init#13.3

... non-static data members are initialized in the order they were declared in the class definition (again regardless of the order of the mem-initializers).

cigien
  • 57,834
  • 11
  • 73
  • 112