The Solution section in gnzlbg's SO question boost::range::join for multiple ranges implies it can join many ranges in one client code call to a custom function variadic template that calls boost::join
and boost::make_iterator_range
. According to that question, answer, and comments, the prior can join 2 ranges and the latter is needed to ensure the non-const
overload of the prior is used. Any containers after the 2nd one are supposedly perfect-forwarded via std::forward
. But my client code can only successfully call it with a maximum of 3 arguments. Anything more fails to compile. What’s wrong and how to fix it? And is there any Boost entity now that joins many ranges?
I’ve copied and pasted that OP’s implementation, editing it here only for whitespace readability and adding the relevant headers:
#include <utility>
#include <boost/range/join.hpp>
template<class C>
auto join(C&& c)
-> decltype(boost::make_iterator_range(std::begin(c), std::end(c)))
{
return boost::make_iterator_range(std::begin(c), std::end(c));
}
template<class C, class D, class... Args>
auto join(C&& c, D&& d, Args&&... args)
-> decltype
(
boost::join
(
boost::join
(
boost::make_iterator_range(std::begin(c), std::end(c)),
boost::make_iterator_range(std::begin(d), std::end(d))
),
join(std::forward<Args>(args)...)
)
)
{
return boost::join
(
boost::join
(
boost::make_iterator_range(std::begin(c), std::end(c)),
boost::make_iterator_range(std::begin(d), std::end(d))
),
join(std::forward<Args>(args)...)
);
}
and added my client code:
#include <deque>
#include <array>
#include <vector>
#include <iostream>
int main()
{
std::deque<int> deq { 0, 1, 2, 3, 4 };
std::array<int, 4> stl_arr { 5, 6, 7, 8 };
int c_arr[3] { 9, 10, 11 };
std::vector<int> vec { 12, 13 };
for (auto& i : join(deq, stl_arr, c_arr))
{
++i;
std::cout << i << ", "; // OK, prints 1 thru 12
}
//join(deq, stl_arr, c_arr, vec); // COMPILER ERROR
}