jeudi 28 juillet 2016

C++ Embded lambda in initializer list for const vector member

I have a class that has a const vector member that holds unique pointers to some objects. When constructed, the sequence object should steal the ownership of the vector of unique pointers that is passed to the constructor so that the sequence object is now the owner of the objects that were owned by the unique pointers in the vector parameter.

class sequence
{
    const std::vector< std::unique_ptr< statement > > m_statements;

    sequence( std::vector< std::unique_ptr< statement > > & statements );
};

The first time I tried to implement the constructor, I did the following :

sequence::sequence( vector< unique_ptr< statement > > & statements )
    m_statements( statements )
{
}

But of course this does not compile since one can't copy-construct a unique_ptr and thus can't copy-construct a vector.

C++ doesn't allow to initialize const members in the body of the constructor (like Java does with final members), but only within the initializer list. Thus, one possible solution could be to drop the const modifier of m_statement and, using a loop, move the content from one vector to the other in the body of the constructor.

But I want to keep this const modifier.

So I came up with another solution that seems to compile, but because I'm new to C++11, I'm not certain about what it does exacly. The idea was to embed the loop described above into a lambda function so that I could initialize m_statement within the initializer list using a loop and still keep the const modifier on m_statement.

sequence::sequence( vector< unique_ptr< const statement > > & statements ) :
    m_statements(([ & statements ] {
        vector< unique_ptr< const statement > > copied_vec;
        for( auto & stm : statements )
            copied_vec.push_back( move( stm ) );
        return copied_vec;
    })())
{
}

This compiles. But I'm not sure about what happens starting at the return statement of the lambda function.

I assume that a copy of copied_vec made and returned. What happens when you return by value a vector of unique pointers ? Is it a correct way to do what I want, despite being weird, or must I just drop the const modifier on m_statetent ? Thank you.

Aucun commentaire:

Enregistrer un commentaire