C++ Logo

std-proposals

Advanced search

Allow block statement before each member in intializer list

From: Joshua Cannon <joshdcannon_at_[hidden]>
Date: Tue, 23 Jul 2019 19:30:54 -0500
Howdy std-proposals!

I ran into this issue a while ago and decided it might be a good candidate
for a proposal to the standard for a new language feature (if it hasn't
already been proposed). What do y'all think?

*Problem:*
There is no good way to prepare values needed for the initialization of a
member in a constructor's initalizer list.

*Background:*
If you have a member you wish to initialize with arguments that can't
expressly be created from the constructor's arguments or the
already-constructed members, you have to resort to tricks to get everything
working.

As a (contrived) example, let's say I have a class (called Foo) that takes
in a const-reference to a vector. It is going to store a reversed copy of
the vector with all of the elements also incremented as a member.
Additionally, it is going to have a member of type Bar, which is
constructed by taking in iterators to the reversed-and-incremented vector.
There's no easy way to do that today. Some solutions might be to use a
delegating base, use the comma operator (with some assumptions about order
of evaluation of arguments, since we have more than one), or use a dummy
variable (usually a bool, and hopefully marked with [[no_unique_address]])
which we can initialize by calling a method and assuming in the method
which members are and are not initialized.

*Proposal:*
What we really wanted to write was some code in-between the initializer for
the reversed vector, and the initializer for Bar which does the incrementing
.

Example:

class Foo {
    std::vector<int> myVec;
    Bar bar;

public:
    Foo(const std::vector<int>& inVec):
        myVec(inVec.rbegin(), inVec.rend()),
        {
            std::transform
            (
                myVec.begin(),
                myVec.end(),
                myVec.begin(),
                &[](int i){return ++i;}
            );
        },
        bar(myVec.begin(), myVec.end())
    {}
};

*The restrictions:*
Of course, only one block-statement should be allowed before each member
initalizer (with none being allowed after the last one, that's what the
constructor body is for). Each block-statement would only have access to
the constructed variables, etc...

What are y'all's thoughts?
(Thanks in advanced)

Received on 2019-07-23 19:33:02