I have two vectors:
std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 4, 5, 6 };
I want to create an object of std::initializer_list
which holds iterators to the first and last elements of above vectors.
I want to have a function with a variadic template:
template<class... Ts>
void foo(Ts... args)
and inside above function I want to unpack all arguments. So far I implemented:
template<class... Ts>
void foo(Ts... args)
{
std::initializer_list<std::vector<int>::iterator> il{
(std::begin(args), std::end(args))...
};
}
int main()
{
std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 4, 5, 6 };
foo(v1, v2);
}
but it doesn't work as expected due to operator,
. Current implementation creates initializer_list
with two iterators. What I want in this case is to have an initializer_list
with 4 iterators pointing to the first and one past the end element of these two vectors. I want it to be begin
, end
, begin
, end
.
You can make a new pack which is double the length:
#include <vector>
#include <utility>
#include <tuple>
namespace detail {
template<std::size_t... I, class... Ts>
void foo_impl(std::index_sequence<I...>, Ts&... args) {
std::initializer_list<std::vector<int>::iterator> il{
[&]() -> std::vector<int>::iterator {
auto& vec = std::get<I/2u>(std::tie(args...));
return I % 2u == 0u ? std::begin(vec) : std::end(vec);
}()...
};
// ...
}
}
template<class... Ts>
void foo(Ts... args) {
return detail::foo_impl(std::make_index_sequence<sizeof...(args)*2u>{}, args...);
}
Or consider if you need an initializer_list
at all. You might be able to use an array:
template<class... Ts>
void foo(Ts... args) {
std::vector<int>::iterator il[sizeof...(args)*2u];
{
auto* p = std::begin(il);
(((*p++ = std::begin(args)), (*p++ = std::end(args))), ...);
}
// ...
}