C++ Logo

std-proposals

Advanced search

Variables in constructor member initializer list

From: Artyom Lebedev <artyom.lebedev_at_[hidden]>
Date: Wed, 1 Sep 2021 11:44:45 +0300
Hello,

Consider the following code:

class MyClass {
public:
     const int a, b, c;

     MyClass(SomeObject &someObject):
         a(SomeOperation(someObject.GetSomeValue()) * 2),
         b(SomeOperation(someObject.GetSomeValue()) / 3),
         c(SomeOperation(someObject.GetSomeValue()) + 4)
     {}
};

In such a typical case it is very inconvenient to have no possibility to
store value of repeating expression. Also it might be very suboptimal to
repeatedly call some potentially heavy functions to have the same
result. I propose to introduce variables in the members initializer list:

class MyClass {
public:
     const int a, b, c;

     MyClass(SomeObject &someObject):
         int someBaseValue(SomeOperation(someObject.GetSomeValue())),
         a(someBaseValue * 2),
         b(someBaseValue / 3),
         c(someBaseValue + 4)
     {}
};

Possible workarounds:

1. Introduce class member to store temporal value:

class MyClass {
public:
     const int someBaseValue, a, b, c;

     MyClass(SomeObject &someObject):
         someBaseValue(SomeOperation(someObject.GetSomeValue())),
         a(someBaseValue * 2),
         b(someBaseValue / 3),
         c(someBaseValue + 4)
     {}
};

which is waste of space, since that value is not needed after useful
members are initialized.

2. Use static method to shorten repeated expression:

class MyClass {
public:
     const int a, b, c;

     MyClass(SomeObject &someObject):
         a(GetSomeBaseValue() * 2),
         b(GetSomeBaseValue() / 3),
         c(GetSomeBaseValue() + 4)
     {}

     static inline int
     GetSomeBaseValue(SomeObject &someObject)
     {
         return SomeOperation(someObject.GetSomeValue());
     }
};

but there still are repeated calls to potentially heavy operation.

3. Use assignment instead of initialization:

class MyClass {
public:
     int a, b, c;

     MyClass(SomeObject &someObject)
     {
         int someBaseValue = SomeOperation(someObject.GetSomeValue());
         a = GetSomeBaseValue() * 2);
         b = GetSomeBaseValue() / 3);
         c = GetSomeBaseValue() + 4);
     }
};

but it is 1. suboptimal due to wasted members intialization which may be
heavy for some classes, 2. Impossible to use for immutable classes which
do not support assignment, 3. impossible to use for const members.

-- 
Best regards,
Artyom.

Received on 2021-09-01 03:44:50