Я хочу определить функцию, которая принимает различные типы контейнеров: те, которые владеют данными (например, std::vector
), и те, которые не владеют данными (например, boost::iterator_range
).
Я написал следующее :
#include <vector>
#include <boost/range/iterator_range.hpp>
template<typename C>
void fill(C& c, typename C::value_type v){
for (auto& j : c)
j = v;
}
template<typename C> // How to avoid this implementation?
void fill(const C& c, typename C::value_type v){
for (auto& j : c)
j = v;
}
int main(){
std::vector<int> v(10);
auto rng = boost::make_iterator_range(v.begin(), v.end());
fill(v, 1); // Case 1 -- Calling on std::vector
fill(rng, 2); // Case 2 -- Calling on boost::iterator_range
// Case 3 -- Calling with an r-value, requires the overload
fill(boost::make_iterator_range(v.begin(), v.end()), 3);
// Case 4 -- Should not be allowed
// fill(std::vector<int>(10), 4);
}
Моя первая реализация fill
работает хорошо, поскольку принимает оба вида итераторов.
Однако, поскольку boost::iterator_range
не владеет данными, это может быть const
(пока данные не являются константными), поэтому я хотел бы разрешить rvalues в качестве аргументов. Это означает, что мне нужна вторая реализация.
Это единственный способ сделать это? Есть ли способ избежать второй реализации?