vukung vukung - 1 year ago 67
C++ Question

Efficient direct initialization of a std::vector

I have a struct, say

struct A {
A(int n) : n(n) {}
int n;

and I want to initialize a
with some elements. I can do this by using an initialization list, or by emplacing the new elements:

// 1st version: 3 ctors, 3 copy ctors, 3 dtors
std::vector<A> v1{1, 2, 3};

// 2nd version: 3 ctors
std::vector<A> v2;

As the comments show, the first version calls 3 constructors, 3 copy constructors, and 3 destructors. The version with emplace only uses 3 constructors.

Question: Obviously the second version is better, but the first version is more succinct. Can I have the best of both worlds? Can I do a direct initialization without the extra cost?

(Here's a longer version of the
struct that shows what's happening.)

Answer Source

Since A is convertible from int, you can use the range constructor of vector:

auto inits = {1, 2, 3};
std::vector<A> v1{std::begin(inits), std::end(inits)};

Or in a single declaration-statement (assuming you can rely on RVO):

auto v1 = [inits={1, 2, 3}] { return std::vector<A>{std::begin(inits), std::end(inits)}; }();