iota_view::iterator не двунаправленный
От: sergii.p  
Дата: 19.03.26 15:35
Оценка:
всем привет. Такая проблема.

const auto fpsRange = std::ranges::iota_view(1, 32);
auto it = fpsRange.begin();
std::advance(it, 100); // Ok
std::advance(it, -10); // UB


что за фигня? Там же внутри итератора простое число хранится. Почему не разрешить обратный проход?
Или может кто знает, как сделать с минимумом телодвижений двунаправленный. Идея в том, чтобы заработал такой код

const auto testFps = [](int fps) { return fps < 15; };
auto it = std::ranges::lower_bound(fpsRange, true, std::ranges::less{}, [&](int fps){ return !testFps(fps); });


Сейчас он уверенно виснет.
Re: iota_view::iterator не двунаправленный
От: rg45 СССР  
Дата: 19.03.26 16:25
Оценка: +1
Здравствуйте, sergii.p, Вы писали:

SP>всем привет. Такая проблема.


SP>
SP>const auto fpsRange = std::ranges::iota_view(1, 32);
SP>auto it = fpsRange.begin();
SP>std::advance(it, 100); // Ok
SP>std::advance(it, -10); // UB
SP>


SP>что за фигня? Там же внутри итератора простое число хранится. Почему не разрешить обратный проход?

SP>Или может кто знает, как сделать с минимумом телодвижений двунаправленный. Идея в том, чтобы заработал такой код

SP>
SP>const auto testFps = [](int fps) { return fps < 15; };
SP>auto it = std::ranges::lower_bound(fpsRange, true, std::ranges::less{}, [&](int fps){ return !testFps(fps); });
SP>


SP>Сейчас он уверенно виснет.


    const std::vector fpsRange {std::from_range, std::views::iota(1, 32)};
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: iota_view::iterator не двунаправленный
От: sergii.p  
Дата: 19.03.26 16:33
Оценка:
Здравствуйте, rg45, Вы писали:

R>
R>    const std::vector fpsRange {std::from_range, std::views::iota(1, 32)};
R>


да, конечно, это решает проблему. Но хотелось бы без выделения памяти.
Re[3]: iota_view::iterator не двунаправленный
От: rg45 СССР  
Дата: 19.03.26 16:45
Оценка:
Здравствуйте, sergii.p, Вы писали:

R>>
R>>    const std::vector fpsRange {std::from_range, std::views::iota(1, 32)};
R>>


SP>да, конечно, это решает проблему. Но хотелось бы без выделения памяти.


Ну, это только собственный iota_view написать.
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: iota_view::iterator не двунаправленный
От: rg45 СССР  
Дата: 19.03.26 18:44
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>да, конечно, это решает проблему. Но хотелось бы без выделения памяти.


Вообще, странный какой-то случай — бинарный поиск по арфметической последовательности. Нафига искать то, что вычисляется с константной сложностью?
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 19.03.2026 18:46 rg45 . Предыдущая версия .
Re[4]: iota_view::iterator не двунаправленный
От: sergii.p  
Дата: 20.03.26 09:34
Оценка:
Здравствуйте, rg45, Вы писали:

R>Вообще, странный какой-то случай — бинарный поиск по арфметической последовательности. Нафига искать то, что вычисляется с константной сложностью?


да, у меня странный случай. У камеры есть максимальный fps, который она отдаёт. Но камера запросто его может не поддерживать а отдавать только потому, что он там жёстко прошит. Поэтому из последовательности fps: 1, 2, 3 ... н-р 30 надо выбрать максимальный, который камера ещё принимает. Каждая попытка — обращение по сети — долго. В общем, бинарный поиск тут самое то. Да и я же использую не арифметическую последовательность, а проекцию по ней.
Re[5]: iota_view::iterator не двунаправленный
От: rg45 СССР  
Дата: 20.03.26 09:45
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>да, у меня странный случай. У камеры есть максимальный fps, который она отдаёт. Но камера запросто его может не поддерживать а отдавать только потому, что он там жёстко прошит. Поэтому из последовательности fps: 1, 2, 3 ... н-р 30 надо выбрать максимальный, который камера ещё принимает. Каждая попытка — обращение по сети — долго. В общем, бинарный поиск тут самое то. Да и я же использую не арифметическую последовательность, а проекцию по ней.


Ну это ты реализовал через поиск и через проекцию, непонятно зачем. Тебе же, имея значения 15, нужно найти значение 14? А имея значение 20, значение 19? Возникает ощущение, что помимо значений, для тебя какую-то ценность имеют также итераторы этой арифметической последовательности.

Ну либо у тебя какой-то обобщённый алгоритм, на вход которого могут приходить произвольные упорядоченные последовательности, в т.ч. и разреженные, а iota ты используешь просто для тестирования?
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 20.03.2026 9:59 rg45 . Предыдущая версия . Еще …
Отредактировано 20.03.2026 9:52 rg45 . Предыдущая версия .
Re[6]: iota_view::iterator не двунаправленный
От: sergii.p  
Дата: 20.03.26 10:39
Оценка:
Здравствуйте, rg45, Вы писали:

R>Тебе же, имея значения 15, нужно найти значение 14? А имея значение 20, значение 19?


функция testFps чисто для отладки. На самом деле это что-то
auto testFps = [](const int fps) {
    const auto config = createConfig(fps);
    const auto errCode = sendRequest(config);
    if(errCode == WrongFps) return false;
    else if(errCode == NoError) return true;
    else return repeatRequest(config);
};


то есть число 15 сидит где-то в камере. Но она его не отдаёт. Потому что там сидят такие же раздолбаи-программисты и могут выдавать чушь в ответах. Камера отдаёт только теоретически возможный fps (н-р 30). А нужно найти реальный, который камера способна принимать. Короче, классическая игра "угадай число". Вот в учебниках какие-то мудрённые алгоритмы пишут. А надо так

const auto askNum = [](int num) { std::cout << "Загаданное число меньше " << num << "? (l|g)"; char answer; std::cin >> answer; return answer == 'l'; };
const auto sequence = std::iota_view(1, 100);
const auto littleBitMagic = 42;
auto it = std::ranges::lower_bound(sequence, littleBitMagic, [&](int num, int) { return askNum(num); } });
std::cout << "Ответ: " << *it;


но это если бы дедушка была бабушкой iota_view умел ходить взад.
Re: iota_view::iterator не двунаправленный
От: Chorkov Россия  
Дата: 20.03.26 10:42
Оценка: 2 (1)
Здравствуйте, sergii.p, Вы писали:

SP>всем привет. Такая проблема.


SP>
SP>const auto fpsRange = std::ranges::iota_view(1, 32);
SP>auto it = fpsRange.begin();
SP>std::advance(it, 100); // Ok
SP>std::advance(it, -10); // UB
SP>


SP>что за фигня? Там же внутри итератора простое число хранится. Почему не разрешить обратный проход?

SP>Или может кто знает, как сделать с минимумом телодвижений двунаправленный. Идея в том, чтобы заработал такой код

SP>
SP>const auto testFps = [](int fps) { return fps < 15; };
SP>auto it = std::ranges::lower_bound(fpsRange, true, std::ranges::less{}, [&](int fps){ return !testFps(fps); });
SP>


SP>Сейчас он уверенно виснет.


На каком компиляторе?

https://godbolt.org/z/YWM4Ya8rh
"У меня все работает".

Можно еще boost.ranges посмотреть.
Re[2]: iota_view::iterator не двунаправленный
От: sergii.p  
Дата: 20.03.26 10:59
Оценка:
Здравствуйте, Chorkov, Вы писали:

C>https://godbolt.org/z/YWM4Ya8rh

C>"У меня все работает".

https://godbolt.org/z/x8jbYn9qq Похоже только prev/advance валится. Странно, я думал, lower_bound реализован на этих примитивах. Походу это не так. Но всё равно страшно такое тащить в прод. Похоже классическое UB.
Re[3]: iota_view::iterator не двунаправленный
От: Chorkov Россия  
Дата: 20.03.26 11:34
Оценка: 12 (2)
Здравствуйте, sergii.p, Вы писали:

SP>Здравствуйте, Chorkov, Вы писали:


C>>https://godbolt.org/z/YWM4Ya8rh

C>>"У меня все работает".

SP>https://godbolt.org/z/x8jbYn9qq Похоже только prev/advance валится. Странно, я думал, lower_bound реализован на этих примитивах. Походу это не так. Но всё равно страшно такое тащить в прод. Похоже классическое UB.


Используйте std::ranges::advance вместо std::advance.
https://godbolt.org/z/caGxKMa6T
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.