Добавить в стандартные контейнеры перегрузки begin(), end() с rvalue ref-qualifiers, возвращающие move_iterator<iterator>

Andrey Davydov
Andrey Davydov

Рассмотрим такой код:

struct OnlyMovable {
    OnlyMovable(OnlyMovable&&) = default;
    OnlyMovable(OnlyMovable const &) = delete;
};

OnlyMovable modify(OnlyMovable o)
{
    // do something with `o`
    // ...

    return o;
}

std::vector<OnlyMovable> produce();

// я предполагаю, что реализация std::transform от range в С++20
// должна работать примерно так
template<typename Range, typename OutIt, typename Functor>
void transform(Range && range, OutIt out, Functor f)
{
    using std::begin, std::end, std::forward;
    std::transform(begin(forward<Range>(range)),
                   end  (forward<Range>(range)),
                   out, f);
}

void test()
{
    std::vector<OnlyMovable> out;
    transform(produce(), std::back_inserter(out), modify);
}

Сейчас он не скомпилируется, так как у нас не получится передать элемент вектора в функцию modify по значению. Это можно поправить, если заменить return type функции produce() на что-то подобное:

template<typename T>
struct myvector {
    using iterator = T*;
    using const_iterator = T const *;

    iterator                        begin()        & ;
    iterator                        end()          & ;
    const_iterator                  begin()  const & ;
    const_iterator                  end()    const & ;
    std::move_iterator<iterator>    begin()        &&;
    std::move_iterator<iterator>    end()          &&;
};

и, соответственно, добавить перегрузки функций std::begin, std::end от rvalue-ranges.

1
рейтинг
Нет комментариев
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения