使用带有可变参数的vector::insert

Use vector::insert with varidic arguments

本文关键字:vector 参数 insert 变参      更新时间:2023-10-16

我想使用带有可变参数的模板函数将多个向量组合为一个。我有一个问题与三个或更多的向量,下面我当前的代码:

#include <iostream>
#include <vector>
#include <numeric>
template<typename _Ty, typename ..._Args>
std::vector<_Ty> combine(const std::vector<_Ty> &a, const _Args &...args) {
  // Determine size of new vector
  std::vector<std::size_t> sizes = { a.size(), args.size()... };
  std::size_t size = std::accumulate(sizes.begin(), sizes.end(), 0);
  // Create vector with new size
  std::vector<_Ty> result(size);
  // Insert all vectors into this one
  result.insert(a.begin(), a.end(), result.end());
  result.insert(result.end(), args.begin()..., args.end()...);
  return result;
}
int main(int argc, char *argv[], char *envp[]) {
  std::vector<int> a = { 0, 1, 2, 3, 4 };
  std::vector<int> b = { 4, 3, 2, 1, 0 };
  std::vector<int> c = { 1, 1, 1, 1 };
  std::cout << combine(a, b).size() << std::endl;
  std::cout << combine(a, b, c).size() << std::endl; // <-- Does not compile
  std::cin.ignore();
  return 0;
}  

所以确切的问题是combine(a, b, c)不能编译。我知道为什么。因为这一行:

result.insert(result.end(), args.begin()..., args.end()...);

编译为:

result.insert(result.end(), b.begin(), c.begin(), b.end(), c.end());

但是我不知道如何调用result。使用可变参数插入,以便编译为:

result.insert(result.end(), b.begin(), b.end());
result.insert(result.end(), c.begin(), c.end());

一种可能是:

std::vector<std::vector<_Ty> all = { a, args...};
for (const auto &vec : all) {
    result.insert(vec.begin(), vec.end());
}

但是这需要所有向量....的第二个副本任何想法?谢谢你!

标准的技巧是使用类似于expander的东西:

template<typename _Ty, typename ..._Args>
std::vector<_Ty> combine(std::vector<_Ty> a, const _Args &...args)
                      // ^^^^^^^^^^^^^^^^^^ by-value
{
    using expander = int[];
    expander{0,
        (void(a.insert(a.end(), args.begin(), args.end())), 0)...
    };
    return a;
}

旁注,_Ty_Args为保留名

相关文章: