Жалобы на ranges.

d-yaroshev
d-yaroshev

Я не уверен в том, что у меня на 100% актуальные данные
Проблема 1: auto.

а)

for (auto x : range)

 - сейчас означает создать копию объекта из range. В range-v3 оно начинает иметь семантику auto&, но не всегда, а только для прокси итераторов. В шаблонном контексте вообще прийдется отказыватся от auto и использовать

for (typename Range::value_type x : range)

, что менее приятно. Вообще auto в циклах становится плохой практикой.

б) Вместо auto& прийдется использовать auto&&, которое раньше было зарезвировано исключительно для магов. При условии что ranges должны делать код проще, не кажется что это здорово.

в)

Я не уверен что будет работать structure binding:

 

template <typename Pairs>
void update_first(Pairs pairs) {
  for (auto& [first, second] : range_of_pairs)
    update(first);
}

Я не могу сказать, что очень понимаю как оно устроено, но вызов этой функции с zip_view кажется сомнительным. (мб опять нужен auto&&)

Проблема 2: предикаты.

Все на 100% должно быть шаблонным, иначе получаются непонятные ошибки компиляции.
Например вот это не компилируется. 

struct map_less {
  template <typename T>
  bool operator()(const T& x, const T& y) const {
    return x.first < y.first;
  }
};

int main() {
  std::vector<int> keys = {1, 3, 2};
  std::vector<std::string> values = {"a", "c", "b"};
  sort(view::zip(keys, values), map_less{});
}

Даже можно разобраться почему но от этого не сильно приятнее.


В целом - все это не страшно, можно отслеживать и опытные разработчики на С++ со всем справятся. Просто грустно что библиотека, которая главным образом должна делать код проще требует очередное know-how. 

 

2
рейтинг
6 комментариев
yndx-antoshkka
Пункт а) характерен не только для ranges а для итераторов в целом. Уже сейчас можно задать итератору свой reference тип, и итератор начнёт себя вести как прокси:
struct write_trough_iterator {
using value_type = int;
using reference = std::reference_wrapper<int>;
...
};

Более того, в стандарте есть не очень красивый кусок, где уже так происходит:
#include <iostream>
#include <vector>
#include <iterator>

int main() {
std::vector<bool> v = {true, true};
std::copy(v.cbegin(), v.cend(), std::ostream_iterator<bool>(std::cout));
for (auto val: v) val = false; // Surprise
std::copy(v.cbegin(), v.cend(), std::ostream_iterator<bool>(std::cout));
}

К счастью, насколько мне известно, текущее предложение по ranges не добавляет новых proxy итераторов open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4651.pdf
yndx-antoshkka
d-yaroshev
yndx-antoshkka,

Все правда.

Насколько я понимаю, vector<bool> не удовлетворяет Container, значит что сейчас алгоритмы не обязаны с ним работать. Ну, мб алгоритмы из стандартной библиотеки. У своих алгоритмов я точно пишу requires ForwardIterator<I> и рассчитываю на то ссылки настоящие.

Тем не менее - предложения Eric Niebler про прокси итераторы и common_reference уже есть
open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0022r0.html
d-yaroshev
yndx-antoshkka
Пункт б) актуален только для прокси итераторов/рейнжей (в остальных случаях auto& и const auto& выглядят более вменяемо). И да, лично я бы такую магию вне Хогвартса особо не использовал.
yndx-antoshkka
d-yaroshev
yndx-antoshkka, прокси итераторы, видимо, идут в нашу жизнь. Хотелось бы чтобы с ними было легко работать.
d-yaroshev
yndx-antoshkka
За structure binding в пункте в) прослежу (в Стандарте С++ должно работать).

Можете скинуть сообщения компилятора, которые возникают в пункте в) с предикатом? Похоже на баг в ranges.
yndx-antoshkka
d-yaroshev
yndx-antoshkka, извиняюсь что долго не отвечал.

Я жаловался на это Эрику, он сказал что ничего не сделаешь: github.com/ericniebler/range-v3/issues/545
d-yaroshev
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).