Является ли array :: operator [] фактически исключением? - PullRequest
4 голосов
/ 14 марта 2019

Per cppref , перегрузки в настоящее время не указаны noexcept. Но я думаю, что они на самом деле noexcept, верно? Так как

  1. Проверка границ не выполняется. Так что нет out_of_range исключений, таких как array::at.
  2. Если ввод за пределами границ, происходит низкоуровневая ошибка или нарушение доступа, что выходит за рамки исключений C ++ (я полагаю).

Ответы [ 2 ]

8 голосов
/ 14 марта 2019

Причина, по которой operator[] не помечен как noexcept, заключается в том, что он имеет "узкий контракт", т. Е. Значение индекса должно находиться в диапазоне 0 ... N-1. Если переданное значение не находится в этом диапазоне, поведение не определено, и (кто знает?) Функция может выдать.

Стандарт довольно непротиворечив в том, что не следует помечать вещи как «узкие контракты» как исключение. Это неофициально известно как «правило Лакоса».

Обратите внимание, что библиотека IMPLEMENTERS может свободно добавлять noexcept, если стандарт не указывает это, если они выбирают. Я подумаю о добавлении этого в libc ++.

[Позже: оказывается, что libc ++ делает это уже для string и string_view, но не vector, array или deque]

[Позже: libc ++ теперь помечает operator[] как noexexcept для vector / array и deque.]

0 голосов
/ 14 марта 2019

Стандартное состояние по отношению к оператору [] для std::array:

26.3.7 Массив шаблонов классов [массив]

26.3.7.1Обзор массива шаблонов классов [ array.overview ]

namespace std {
template <class T, size_t N>
struct array {
...  

// element access:
constexpr reference operator[](size_type n);
constexpr const_reference operator[](size_type n) const;

Как мы видим, они не noexcept.

В то время как такие члены, как data(), четко обозначены noexcept

constexpr T * data() noexcept;
constexpr const T * data() const noexcept;
...