Отключение проверки границ для векторов С++
С 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) проверили итераторы для некоторых типов построек