lundi 2 mai 2016

How do I write a make_vector similar to std::make_tuple?

Instead of creating vectors like this:

  std::vector<int>     v1{1,2,3};
  std::vector<double>  v2{1.1,2.2,3.3};
  std::vector<Object>  v3{Object{},Object{},Object{}};  

I'd like to create them with a generic function:

  auto v1 = make_vector(1,2,3);
  auto v2 = make_vector(1.1,2.2,3.3);
  auto v3 = make_vector(Object{},Object{},Object{}); 

Similar to std::make_pair and std::make_tuple, here was my attempt for a vector:

#include <iostream>
#include <vector>
#include <utility>

template <typename... T>
auto make_vector(T&&... args)
{
    using first_type = typename std::tuple_element<0, std::tuple<T...>>::type;
    return std::vector<first_type>{std::forward<T>(args)...};
}

It compiles, but when I attempt to use it:

auto vec = make_vector(1,2,3);  


m.cpp: In instantiation of ‘auto make_vector(T&& ...) [with T = {int, int, int}]’:
m.cpp:16:30:   required from here
m.cpp:8:78: error: invalid use of incomplete type ‘class std::tuple_element<0ul, std::tuple<int, int, int> >’
     using first_type = typename std::tuple_element<0, std::tuple<T...>>::type;
                                                                              ^
In file included from m.cpp:3:0:
/usr/include/c++/5/utility:85:11: note: declaration of ‘class std::tuple_element<0ul, std::tuple<int, int, int> >’
     class tuple_element;
           ^
m.cpp:9:60: error: invalid use of incomplete type ‘class std::tuple_element<0ul, std::tuple<int, int, int> >’
     return std::vector<first_type>{std::forward<T>(args)...};
                                                            ^
In file included from m.cpp:3:0:
/usr/include/c++/5/utility:85:11: note: declaration of ‘class std::tuple_element<0ul, std::tuple<int, int, int> >’
     class tuple_element;
           ^
m.cpp: In function ‘int main()’:
m.cpp:16:30: error: ‘void v1’ has incomplete type
   auto v1 = make_vector(1,2,3);  

How can I make a generic routine,
that uses the first type of the first parameter to instantiate the vector?
How can I forward the arguments as initializer values to the vector?

Aucun commentaire:

Enregistrer un commentaire