My constructor originally took a std::vector<>
but I couldn't figure out how to get a braced list to initialize it. I got it working after changing to an std:initializer_list<>
. I found two ways: 1) passing the initializer_list in as a parameter to the array constructor (commented out in code below) and 2) using the std::copy
algo (as seen in code below).
Now, I need to create this object with a std::vector<>
and can't figure out how to convert it to the initializer_list. I could make a second constructor that takes a vector, but as an exercise I'd like to get this working with one constructor if possible.
Any ideas?
class One: public Base {
public:
One( Two* ptwo_in, std::initializer_list<Three> ilthree ) :
ptwo( ptwo_in )//,
//athree_( ilthree )
{
athree_.reserve( ilthree .size() );
std::copy( ilthree .begin(), ilthree .end(), athree_.begin() );
}
Two* ptwo_;
std::vector<Three> athree_;
};
// Works fine:
new One( &two, { Three( args ),
Three( args ),
Three( args ), } )
// Doesn't work:
std::vector<Three>* pathreeSomething
athreeOther.push_back( new One( ptwoLocal, *pathreeSomething ) );
On that third line of code it works with replacing initializer_list with vector, true. But I don't want to pass around a whole vector as an arg.
You're going to construct a vector anyway (One::athree_
). So just move the vector passed to the constructor rather than copy it:
class One: public Base {
public:
One(Two* ptwo_in, std::vector<Three> ilthree)
: ptwo{ptwo_in}
, athree_{std::move(ilthree)}
{ }
private:
Two* ptwo_;
std::vector<Three> athree_;
};
This is a common pattern in C++. Pass by non-const value and use move semantics to avoid copies:
One one{some_ptr, {Three{args}, Three{args}, Three{args}}};
or:
std::vector<Three> vec{ ... };
// moves 'vec' to the ctor parameter, the ctor then moves it to its member
One one{some_ptr, std::move(vec)};
No unnecessary copies that way.