I would like to create a to_vector function that works with input vieweable_ranges. I can easily get this to work if input view and output vector have exactly the same type, but cannot get it to work if the output requires a const cast on the elements of the input range. In my case, the input ranges have non-const pointers, but the output may specify const pointers. I want to use it something like this:
auto a = to_vector( view ); // returns a vector<obj *>. This case is easy
vector<const obj *> b = to_vector( view ); // returns a vector of const pointers. This gives error shown at the end
The standard library has no problem casting pointers when making the vector
vector<const obj *> c( view.begin(), view.end() );
But I can't create a templated function to make it work. I've tried many variations, but I think my closest idea is something like this:
#include <ranges>
#include <vector>
using namespace std::ranges;
template <range Range, typename T = range_value_t<Range>> // default element type, T, based on input range
inline std::vector<T> to_vector(Range&& r) { // idea: user specifies T. (doesn't work)
std::vector<T> v;
if constexpr (std::ranges::sized_range<T>) {
v.reserve(std::ranges::size(r));
}
std::copy(std::ranges::begin(r), std::ranges::end(r), std::back_inserter(v));
return v;
}
The to_vector compiles, but I get an error when I try to require a vector output with an error something like this:
cannot convert std::vector<Obj *,std::allocator<Obj *>>' to 'std::vector<const Obj *,std::allocator<const Obj *>>