Отключение проверки границ для векторов С++

С stl:: vector:

vector<int> v(1);
v[0]=1; // No bounds checking
v.at(0)=1; // Bounds checking

Есть ли способ отключить проверку границ, не переписывая все at() как []? Я использую стандартную библиотеку С++ GNU.

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

Ответ 1

Если вы действительно хотите это сделать (по крайней мере, для быстрого и грязного сравнения профилей), это будет работать, если у вас нет других at() s

#define at(x) operator[](x)

И если вы хотите сохранить at() для разработки и использовать operator[] в процессе производства, просто оберните его в #ifdef.

И если у вас есть другой at(), вы всегда можете редактировать файл #include d <vector>.

Ответ 2

Нет. Проверка границ std::vector::at указана стандартом, и стандартная С++-реализация не может соответствовать стандарту.

Ответ 3

Возможно, лучшим решением является использование [] и использование проверенной реализации стандартной библиотеки для отладки.

Ответ 4

Не стандартный способ. Вы можете отключить исключения в своем компиляторе. Вы можете сделать это с помощью gcc с -fno-exceptions.

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

Ответ 5

На основании вашего комментария, что вы хотели бы включить проверку флажков вкл/выкл, вы можете использовать функцию шаблона-обертки:

template <class T>
inline typename T::reference deref(T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

template <class T>
inline typename T::const_reference deref(const T &cont, typename T::size_type idx)
{
#if BOUNDS_CHECK
    return cont.at(idx);
#else
    return cont[idx];
#endif
}

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

Я признаю, что это выглядит немного уродливо:

deref(vec, 10) = ...;

Ответ 6

Выведите собственный векторный класс в своем собственном пространстве имен, например "uncheckedvector", и переопределите тип() базового вектора at() для использования индекса массива.

Затем использование "с помощью uncheckedvector:: vector" позволит вам переопределить все ваши применения вектора повсюду. Это не сработает, если вы используете полностью квалифицированные типы в любом месте.

Ответ 7

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

Несколько подходов к проверке параметров режима разработки для [] при использовании GCC в Linux:

Некоторые другие интересные обсуждения: vector:: at vs. vector:: operator []

Ответ 8

Если у вас есть разумно согласованные шаблоны доступа (то есть/не произвольный доступ), а не с использованием at() или [], один из способов избежать проверки диапазона - использовать итераторы, используя begin(), end() и advance() или даже лучше, используя стандартные алгоритмы.

Хотя это не решает основной проблемы исправления at() проверки диапазона, некоторые реализации стандартной библиотеки (MSVC) проверили итераторы для некоторых типов построек