Short version:
I need to pass a template class a parameter pack, which is the result of applying a function to another parameter pack. This needs to work within a using
statement.
Background:
As a challenge, I'm writing a generic C++11 version of python's zip()
. In order to do so, I have written a generic zipIterator
template class which can be used to iterate over many iterators simultaneously, yielding a tuples of their values. For example:
#include "zip.hpp"
#include <iostream>
#include <vector>
#include <tuple>
int main(){
std::vector<int> vec = {0,1,2,3};
char arr[] = {'a','b', 'c'};
zipIterator<decltype(vec.begin()), char*, decltype(vec.rbegin())>
itr(vec.begin(), std::begin(arr), vec.rbegin());
zipIterator<decltype(vec.begin()), char*, decltype(vec.rbegin())>
end(vec.end(), std::end(arr), vec.rend());
for(; itr!=end; ++itr){
std::cout << "(" << std::get<0>(*itr) << ", " << std::get<1>(*itr)
<< ", " << std::get<2>(*itr) << ")" << std::endl;
}
}
//output:
//(0, a, 3)
//(1, b, 2)
//(2, c, 1)
The Problem
I would like to make a zip
container class which can be passed containers, and which zips over them by calling std::begin() and std::end() on each one. So far I have this:
template<typename... Containers>
class zip{
public:
using iterator = zipIterator<???>;
zip(Containers... cs) : begin_(iterator(std::begin(cs)...)),
end_(iterator(std::end(cs)...)){};
iterator begin() {return begin_;}
iterator end() {return end_;}
private:
iterator begin_;
iterator end_;
};
My question is: what goes in the place of ???
to make this work? So far I have tried
std::begin(std::declval<Containers>())...
,
decltype(std::begin(Containers)...)
,
std::result_of<std::begin(Containers)>::type...
,
and many more variations on this.
Sorry if this is a repeat. I read the following Stack Overflow answers and they all seem to be related, but I don't think they are quite what I am looking for: