C++ Logo

std-proposals

Advanced search

Re: Variables in constructor member initializer list

From: Bo Persson <bo_at_[hidden]>
Date: Wed, 1 Sep 2021 10:58:22 +0200
On 2021-09-01 at 10:44, Artyom Lebedev via Std-Proposals wrote:
> 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.
>

You can alredy get a similar effect by using a delegating constructor:

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

     MyClass(SomeObject &someObject)
      : MyClass(SomeOperation(someObject.GetSomeValue()))
     {}

private:
     MyClass(int someBaseValue) :
         a(someBaseValue * 2),
         b(someBaseValue / 3),
         c(someBaseValue + 4)
     {}
};

Received on 2021-09-01 03:58:32