Reputation: 16334
How can I convert a template parameter pack of IteratorTypes
to a tuple of the respective value_type
s?
I tried the following, but it failed with
error: wrong number of template arguments (2, should be 1)
using ValueTypes = typename std::iterator_traits<IteratorTypes...>::value_type;
^
#include <type_traits>
#include <vector>
#include <tuple>
template <typename ... IteratorTypes>
void foo(IteratorTypes&&...its)
{
using ValueTypes = typename std::iterator_traits<IteratorTypes...>::value_type;
static_assert(std::is_same<std::tuple<ValueTypes>,std::tuple<int,float>>::value, "types do no match");
}
int main() {
std::vector<int> int_vec(1);
std::vector<float> float_vec(1);
foo(int_vec.begin(), float_vec.begin());
return 0;
}
Upvotes: 1
Views: 192
Reputation: 137345
The ...
goes immediately after the pattern you want to expand.
using ValueTypes = std::tuple<typename std::iterator_traits<IteratorTypes>::value_type...>;
static_assert(std::is_same<ValueTypes, std::tuple<int,float>>::value, "types do no match");
Also, you should probably std::decay
IteratorTypes
before passing it to iterator_traits
, or take them by value rather than by forwarding reference.
Upvotes: 4
Reputation: 69892
...or to make it easier to read:
#include <type_traits>
#include <vector>
#include <tuple>
#include <utility>
template <typename ... IteratorTypes>
void foo(IteratorTypes&&...its)
{
using value_type_tuple = std::tuple<typename IteratorTypes::value_type...>;
using desired_tuple = std::tuple<int, float>;
static_assert(std::is_same<value_type_tuple , desired_tuple>::value, "types do no match");
}
int main() {
std::vector<int> int_vec(1);
std::vector<float> float_vec(1);
foo(int_vec.begin(), float_vec.begin());
return 0;
}
Upvotes: 0