
Size: a a a
C++20 has has me me seeing seeing double double
C++20 has has me me seeing seeing double double
noexcept(noexcept(iter.dereference()))
? Это одинаковые имена для разных вещей.noexcept
— это noexcept specifier, который является частью типа функции (но не участвует в перегрузке, т. е. две функции не могут отличаться только этим) и описывает, бросает ли функция исключения. Если исключение должно покинуть noexcept функцию, вместо этого вызывается std::terminate, что обычно означает завершение работы программы. После ключевого слова noexcept в скобках может стоять константное булево выражение. В этом случае то, является ли функция не-бросающей-исключения, зависит от того, во что это выражение вычисляется. Это полезно, если функция шаблонная и она пробрасывает исключения из внешних функций.noexcept
— это noexcept operator. Он применяется к выражению в скобках и возвращает, является ли выражение noexcept (в смысле спецификации noexcept). Этот оператор можно использовать везде, где требуется выражение булевого типа, но чаще всего он используется вкупе с noexcept specifier. Таким образом, сложив два и два, получаем, что noexcept(noexcept(iter.dereference()))
означает, что функция dereference не бросает исключения только в том случае, если метод iterator_type::dereference
не бросает исключения.requires requires
? Тут ситуация похожая, но несколько более сложная.requires
относится к require clause. Это, гм... Спецификатор? ...Который принимает константное булево выражение и запрещает инстанцирование шаблона, если выражение вычисляется в false
. Это фича предназначается для раннего отсечения неправильного использования шаблонов, раньше, чем инстанцирование будет сделано до конца. Принципиально эта фича, строго говоря, не добавляет нового функционала, поскольку подобные проверки можно было делать и раньше с использованием идиомы SFINAE (тот же std::enable_if), но использование requires приводит к куда более ранним диагностикам и, как следствие, более понятным сообщениям об ошибках.requires
относится к requires expression. Это оператор, который применяется к, гм, "requirement-seq" (это кусок синтаксиса с грамматикой, отличающейся от грамматики C++) и отвечает на вопрос, является код после него well-formed — т. е. компилируется ли он вообще. Как и оператор noexcept, этот оператор может быть использован всюду, где ожидается булево выражение. В итоге мы получаем, что requires requires { iter.dereference(); }
означает "эта специализация шаблона определена только тогда, когда на переменной iter
можно вызвать метод dereference
(и это не приведёт к ошибке компиляции)".C++20 has has me me seeing seeing double double