Всего auto&
с явным std::move
достаточно.
Но чтобы быть фантазии
struct empty_t{};
template<class It,class B=empty_t>struct range_t:B{
It b,e;
It begin()const{return b;}
It end()const{return e;}
range_t(It s,It f):b(std::move(s)),e(std::move(f)){}
// fancy
template<class S, class F>
range_t(B base, S s, F f):B(std::move(base)),b(s(*this)),e(f(*this)){}
};
template<class It>range_t<It> range(It b, It e){return{std::move(b),std::move(e)};}
template<class B, class S, class F>
auto range(B base, S s, F f){
auto It=std::result_of_t<s(base)>;
return range_t<It,B>{
std::move(base),std::move(s),std::move(f)
};
}
template<class R>
auto move_from(R& r){
using std::begin; using std::end;
return range(std::make_move_iterator(begin(r)), std::make_move_iterator(end(r)));
}
template<class R>
auto move_from(R&& r){
using std::begin; using std::end;
return range(
std::move(r),
[](auto&r){return std::make_move_iterator(begin(r));},
[](auto&r){return std::make_move_iterator(end(r));}
);
}
Теперь, запрещая опечаток,
for(auto i:move_from(produce(str)))
some_function(std::move(i));
будет иметь i
быть перемещены из-копии каждого элемента.
Но это безумие.
Этот метод может быть полезен, если у вас есть итерационный код, основанный на ране/контейнере, который вы хотите быть агностическим.
template<class R, class F>
auto transform_to_vector(R&& r, F&& f){
using std::begin; using std::end;
using rT=std::decay_t<std::result_of_t< f(*begin(std::forward<R>(r))) >>;
std::vector<rT> retval;
for(auto&& e:std::forward<R>(r)){
retval.push_back(f(decltype(e)(e)));
}
return retval;
}
Теперь, вызвав выше move_from(x)
как ваш «диапазон» отличается от вызова его с x
. Вы могли бы представить и другие алгоритмы, написанные так же.
@songyuanyao, Не будет ли это просто привязать ссылку пересылки к значению, возвращаемому оператором '' '' 'итератора ''? И так как итератор возвращает ссылку lvalue на 'std :: string',' std :: string & && 'сворачивается вниз до' std :: string & '. [Вот пример] (http://coliru.stacked-crooked.com/a/14efce4c332a8b9f) – Alejandro
@Alejandro Я думаю, что вы правы. – songyuanyao