Какой самый быстрый способ проверить, находится ли индекс std :: vector вне границ? - PullRequest
0 голосов
/ 13 сентября 2011

Часто я хочу быть уверенным, что однажды нахожусь в границах своего функционального тела. Я делаю это по-разному:

// I don't like this much as it stops the program when I may not want to
assert( idx < v.size() );

if( !(idx < v.size()) )
{
    // take corrective action ...
}

if( v.size() <= idx )
{
    // take corrective action ..
}

Между вторым и третьим методом (и, может быть, другим), который более эффективен?

Ответы [ 3 ]

4 голосов
/ 13 сентября 2011

Большую часть времени вы не собираетесь проверять. Поскольку вы уже проверили пользовательский ввод в тот момент, когда он входит в программу, вам не нужно проверять его где-либо еще.

Если есть вероятность использования неподтвержденного ввода, то вам следует использовать метод at (). Это создаст исключение, если индекс выходит за пределы и ведет себя как operator [] во всех других ситуациях. Исключение приведет к закрытию приложения, если вы явно не отловите и не дадите компенсацию (что следует делать только в том случае, если это допустимый параметр, в противном случае разрешите приложению завершиться (возможно, с сообщением об ошибке, если необходимо)).

Лично я предпочитаю использовать исключение вместо asserts ().
Утверждения могут быть отключены на уровне компилятора (поэтому они бесполезны в производственном коде (только для проверки кода действителен в модульных тестах)), исключения обеспечивают ту же функциональность (быстрое завершение работы приложения, если они запускаются (и как исключения, они позволяют вам регистрировать информацию)). В отличие от утверждений, исключения могут быть перехвачены при необходимости (хотя в основном вы просто хотите, чтобы они убили приложение)).

4 голосов
/ 13 сентября 2011

Просто используйте

idx < vec.size()

и покончите с этим.Вы не собираетесь делать ваше приложение любым быстрее, потратив еще одну минуту на решение этой проблемы.

Кроме того, рассмотрите проверенный доступ:

try {
    vec.at(idx) = stuff;
} catch (std::out_of_range& err) {
    // oh dear god
}
0 голосов
/ 13 сентября 2011

Полагаю, вы зацикливаетесь на этом векторе.Если функция, для которой вы пишете этот код, не вызывается в цикле или чем-то еще, просто не беспокойтесь об этом.Оба оператора компилируются с одинаковыми 3 или 4 инструкциями, в зависимости от векторной реализации вашего компилятора.Если функция вызывается в цикле, сделайте две вещи: сделайте ее встроенной и избавьтесь от проверки.Вместо этого проверьте индекс по границе в вызывающей функции.

Кроме того, просто не беспокойтесь об этом, потому что что-то еще является вашим узким местом.Посмотрите на ваши вызовы API, использование виртуальных функций в циклах, операции с плавающей точкой в ​​int, процедуры сортировки, синхронизации потоков ... поверьте мне, это не повредит.

...