使用模板将多个向量(函数的结果)组合为一个

时间:2019-05-07 13:28:27

标签: c++ c++11 templates stdvector

我想有一个模板函数,其中包含一个vector<T> v和一个函数op,将T映射到vector<U>,并希望将应用{{1} }到f的每个元素向量,以返回v = [op(v [0])的元素,op(v [1])的元素...]。

我发现一个可行的选择是在函数中添加一个示例以允许模板推导:

vector<U>

但是自然地,我只想使用两个参数来产生相同的结果。 我的尝试[用{{1}代替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; } ]:

U

不幸的是,这没有编译。我还担心如果op是复杂方法会浪费时间。

这给了:

decltype(*std::begin(op(*std::begin(c))))

... 所以它似乎与'const'有关。

将如何更正此变体?有更好的选择吗?

1 个答案:

答案 0 :(得分:5)

解引用容器迭代器会产生一个引用(如果容器是const,则为const引用),这就是为什么decltype(*std::begin(op(*std::begin(c))))根据编译器错误产生const U&的原因(而不是U )。

您可以通过以下方法解决此问题:用std::remove_reference再次删除引用(或者,如果您也要删除constvolatilestd::remove_cvref),或者仅向向量询问其实际存储的内容:

decltype(*std::begin(op(*std::begin(c))))-> typename decltype(op(*std::begin(c)))::value_type

我已经继续并删除了不需要的U& ex参数。

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

Demo

您也可以通过命名decltype来避免三次重复:

template <typename Container, typename UnaryOperation>
using applied_op_t = typename decltype(std::declval<UnaryOperation>()(*std::begin(std::declval<Container>())))::value_type;