В чем смысл рекурсивного noexcept ()? - PullRequest
0 голосов
/ 24 мая 2018

Стандартная библиотека определяет подстановки для массивов и std::pair, например, так:

template <class T, size_t N>
void swap(T (&a)[N],
          T (&b)[N]) noexcept(noexcept(swap(*a, *b)));

template <class T1, class T2>
struct pair {
    …
    void swap(pair& p) noexcept(noexcept(swap(first,  p.first)) &&
                                noexcept(swap(second, p.second)));
    …
};

Эффективный Современный C ++ Пункт 14 говорит:

[…], являются ли они *Значение 1008 * зависит от того, являются ли выражения внутри предложений noexcept noexcept.
. Например, для двух массивов Widget их замена равна noexcept, только если для отдельных элементов в массивах noexceptт. е. если swap для Widget равен noexcept.
Это, в свою очередь, определяет, являются ли другие свопы, например, для массивов массивов Widget, noexcept.
Аналогичносвопирование двух std::pair объектов, содержащих Widget s, равно noexcept, зависит от того, является ли своп для Widget s noexcept.

Но из этого объяснения я не могу понять, почему это необходимовложите вызов как noexcept(noexcept(swap(*a, *b))).

Если цель «поменять местами два массива как noexcept как местами обмена», почему не достаточно noexcept(swap(*a, *b))?

различные перегрузки noexcept() или что-то?

1 Ответ

0 голосов
/ 24 мая 2018

Это не «рекурсивный» noexcept, просто есть два варианта использования ключевого слова noexcept:

  • noexcept спецификатор - который обозначаетфункция как noexcept и, необязательно, принимает логическое константное выражение в качестве аргумента

  • noexcept оператор - который принимает выражение в качестве аргумента и возвращает логическое константное выражение , представляющее, является ли выражение noexcept


В вашем случае:

//          `noexcept` operator
//          v~~~~~~~~~~~~~~~~~~~~~
   noexcept(noexcept(swap(*a, *b)))
// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// `noexcept` specifier
...