Как вы проверяете границы с помощью std span? - PullRequest
0 голосов
/ 02 августа 2020

std::vector и почти все другие контейнеры имеют очень удобный способ проверки границ: at(). std::span этого явно не имеет.

Ответы [ 2 ]

1 голос
/ 02 августа 2020

paper , который представил диапазон в стандартной библиотеке, говорит:

Проверка диапазона и безопасность границ

Все обращения к данным, инкапсулированным диапазоном, концептуально проверяются диапазоном, чтобы гарантировать, что они остаются в пределах диапазона. Что на самом деле происходит в результате несоблюдения ограничений безопасности диапазона во время выполнения, так это неопределенное поведение.

То есть операции имеют узкие контракты, что дает свободу разработчикам.

Если ваша стандартная библиотека не позволяет вам контролировать поведение до соответствующей степени детализации. gsl-lite предлагает замену с настраиваемым поведением при нарушении контракта. Microsoft GSL раньше можно было настраивать, но теперь всегда завершается при нарушении контракта, что обсуждается здесь (что на самом деле может быть тем, что вам нужно).

1 голос
/ 02 августа 2020

Довольно неуклюже, но примерно так:

  1. с использованием позиции
template<class Container>
auto& at(Container&& c, std::size_t pos){
    if(pos >= c.size())
        throw std::out_of_range("out of bounds");
    return c[pos];
}
с использованием итераторов:
template<class Iterator, class Container>
auto& at(Container&& c, Iterator&& it){
    if(std::distance(c.begin(), it) >= c.size())
        throw std::out_of_range("out of bounds");
    return *it;
}
...