mardi 7 mai 2019

Combine multiple vectors (results of function) into one with template

I'd like to have a templated function taking in a vector<T> v and a function op, mapping T to vector<U> and would like to concatinate the results of applying f to every element vector of v to return a vector<U> = [ Elements of op(v[0]), Elements of op(v[1]) ...].

A working option I found was adding an example in the function to allow for template deduction:

template <typename Container>
Container& concat(Container& c1, Container const& c2) {
  c1.insert(end(c1), begin(c2), end(c2));
  return c1;
}

template <typename Container, typename UnaryOperation, typename U>
inline auto to_vec_from_vectors(Container& c, UnaryOperation&& op, U& ex)
    -> std::vector<U> {
  std::vector<U> v;
  for (auto& e : c) {
    std::vector<U> opv = op(e);
    concat(v, opv);
  }
  return v;  
}

But naturally I'd like to produce the same result with only the two parameters. My attempt [replacing U with decltype(*std::begin(op(*std::begin(c))))]:

template <typename Container, typename UnaryOperation, typename U>
inline auto to_vec_from_vectors(Container& c, UnaryOperation&& op, U& ex)
    -> std::vector<decltype(*std::begin(op(*std::begin(c))))> {
  std::vector<decltype(*std::begin(op(*std::begin(c))))> v;
  for (auto& e : c) {
    std::vector<decltype(*std::begin(op(*std::begin(c))))> opv = op(e);
    concat(v, opv);
  }
  return v;  
}

Unfortunately this didn't compile. I'm also worried of wasting time if op is complex method.

This gave:

error: conversion from ‘std::vector<U>’ to non-scalar type ‘std::vector<const U&, std::allocator<const U&> >’ requested

error: forming pointer to reference type ‘const U&

... so it seems to be related to 'const'.

How would this variant be corrected? Are there better alternatives?

Aucun commentaire:

Enregistrer un commentaire