这是C++中一个简单的两容器zip函数:

template <typename A, typename B>
std::list<std::pair<A, B> > simple_zip(const std::list<A> & lhs,
                                       const std::list<B> & rhs)
{
  std::list<std::pair<A, B> >  result;
  for (std::pair<typename std::list<A>::const_iterator,
                 typename std::list<B>::const_iterator> iter
       =
       std::pair<typename std::list<A>::const_iterator,
                 typename std::list<B>::const_iterator>(lhs.cbegin(),
                                                        rhs.cbegin());
       iter.first != lhs.end() && iter.second != rhs.end();
       ++iter.first, ++iter.second)
  {
    result.push_back( std::pair<A, B>(*iter.first, *iter.second) );
  }
  return result;
}

我如何将其扩展到具有可变参数模板的任意数量的容器?

我希望general_zip接受tuplelist(每个列表可以包含不同的类型),并返回listtuple

最佳答案

看来这应该工作

std::list<std::tuple<>> simple_zip() {
  return {};
}

template <typename ...T>
std::list<std::tuple<T...>> simple_zip(std::list<T>... lst)
{
  std::list<std::tuple<T...>>  result;
  for (int i = 0, e = std::min({lst.size()...}); i != e; i++) {
    result.emplace_back(std::move(lst.front())...);
    [](...){} ((lst.pop_front(), 0)...);
  }
  return result;
}

@Potatoswatter表示(IMO)很好,当列表大小不同时,这可能会复制所需的内容,并且仅使用迭代器会更好,因为pop_front的功能比实际需要的更多。我认为以下代码以更多代码为代价“修复”了迭代器。
template <typename ...T>
std::list<std::tuple<T...>> simple_zip(std::list<T>... lst)
{
  std::list<std::tuple<T...>>  result;
  struct {
    void operator()(std::list<std::tuple<T...>> &t, int c,
             typename std::list<T>::iterator ...it) {
      if(c == 0) return;
      t.emplace_back(std::move(*it++)...);
      (*this)(t, c-1, it...);
    }
  } zip;
  zip(result, std::min({lst.size()...}), lst.begin()...);
  return result;
}

std::list<std::tuple<>> simple_zip() {
  return {};
}

关于C++ zip可变参数模板,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10420380/

10-11 15:50