Efficient and elegant way to initialize a vector

Given the following C ++ 14 code:

struct A { /* heavy class, copyable and movable */ };

// complex code to create an A
A f(int);
A g(int);
A h(int);

const std::vector<A> v = { f(1), g(2), h(3) };

I know that Ain the initializer_list file is copied to the vector, instead of being moved (there are a lot of questions about this in stackoverflow).

My question is: how can I move them to a vector?

I was only able to make ugly IIFE (which supports vconst) and just avoids initializer_list:

const std::vector<A> v = []()
{
    std::vector<A> tmp;
    tmp.reserve(3);
    tmp.push_back( f(1) );
    tmp.push_back( g(2) );
    tmp.push_back( h(3) );
    return tmp;
}();

Can this be made elegant and efficient?

PD: vshould be std::vector<A>for later use

+6
source share
2 answers

, "", ( std::array), , , move_iterator, vector.

std::array<A, 3> init = { f(1), g(2), h(3) };

std::vector<A> v{std::make_move_iterator(init.begin()), 
                 std::make_move_iterator(init.end())};

.

+7

++ 14, - auto.

-...

#include <vector>

struct A
 { };

A f (int) { return {}; } 
A g (int) { return {}; } 
A h (int) { return {}; } 


int main ()
 {
   static const auto getVA = [](auto && ... args)
    {
      using unused = int[];

      std::vector<A> ret;

      ret.reserve(sizeof...(args));

      (void)unused { 0,
            (ret.emplace_back(std::forward<decltype(args)>(args)), 0)... };

      return ret;
    };

   auto va = getVA(f(1), g(2), h(3));
 }

(-) , ++ 11, getVA

template <typename ... Args>
std::vector<A> const getVA (Args&& ... args)
 {
   using unused = int[];

   std::vector<A> ret;

   ret.reserve(sizeof...(args));

   (void)unused { 0, (ret.emplace_back(std::forward<Args>(args)), 0)... };

   return ret;
 }
+2

Source: https://habr.com/ru/post/1016853/


All Articles