Какова точная цитата из стандарта C++, в которой говорится, что ошибка вывода типа при выведении аргумента шаблона не является ошибкой (SFINAE)?

Следующая цитата из CPPreference понятна:

Это правило применяется при разрешении перегрузки шаблонов функций: если замена явно указанного или выведенного типа для параметра шаблона не удалась, специализация отбрасывается из набора перегрузки вместо того, чтобы вызывать ошибку компиляции.

Каковы соответствующие цитаты из стандарта C++17 (или более поздних версий), в которых говорится, что ошибка вывода типа не является ошибкой?

Насколько мне известно, параграф 8 из C++17:17.8.2 ([temp.deduct]) считается базовой цитатой для SFINAE (Зависит ли SFINAE от вывода типа? , Что такое "немедленное" context», упомянутый в стандарте C++11, к которому применяется SFINAE?):

Если замена приводит к недопустимому типу или выражению, вывод типа невозможен. Недопустимый тип или выражение — это тип, который был бы неправильно сформирован и требовал бы диагностики, если бы он был написан с использованием замененных аргументов. [ Примечание. Если диагностика не требуется, программа по-прежнему некорректна. Проверка доступа осуществляется в рамках процесса замены. - конец примечания ] Только недопустимые типы и выражения в непосредственном контексте типа функции и типов параметров ее шаблона могут привести к сбою вывода. [ Примечание. Подстановка в типы и выражения может привести к таким эффектам, как создание экземпляров специализаций шаблона класса и/или специализаций шаблона функции, генерация неявно определенных функций и т. д. Такие эффекты не находятся в «непосредственном контексте» и могут в результате программа будет неправильно сформирована. — последнее примечание]

Это можно интерпретировать, поскольку an invalid type or expression is one that would be ill-formed [...] if... означает, что в данном контексте оно на самом деле не является неправильным. А поскольку type deduction fails с an invalid type or expression, то ошибка вывода типа не является неправильной. Другая причина может заключаться в том, что, поскольку это явно не указано как ошибка, выведение типа не является ошибкой.

Однако сначала в примечании говорится If no diagnostic is required, the program is still ill-formed («есть» в настоящем времени). Кроме того, хотя «выведение типа не удалось» повторяется в этом разделе несколько раз, не указано, что происходит, когда такое выведение типа не удается. Я также искал в разделах, посвященных разрешению перегрузки и генерации набора кандидатов (поскольку отсутствие других жизнеспособных кандидатов вызывает ошибку компиляции), но я не смог найти явного предложения, такого как CPPreference: the specialization is discarded from the overload set instead of causing a compile error.

Есть ли какая-либо другая более явная цитата, которую мне не хватает в Стандарте, утверждающая, что когда выведение типа не удается при выведении аргументов шаблона, программа не является неправильной?

Примечание. Я не ставлю под сомнение поведение или механизм, я просто ищу более явные цитаты.

Возможно, эта ссылка поможет Что такое «непосредственный контекст», упомянутый в стандарте C++11, к которому применяется SFINAE (Последний «ответ» был действительно полезен для моей мысленной модели)

Pepijn Kramer 27.08.2024 21:09
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
1
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Упомянутая цитата действительно относится к первой половине SFINAE:

Если замена приводит к недопустимому типу или выражению, вывод типа невозможен. Недопустимый тип или выражение — это тип, который был бы неправильно сформирован и потребовал бы диагностики, если бы он был написан в том же контексте с использованием замененных аргументов.

[temp.deduct.general]

Перевод: ошибка замены приводит к ошибке вывода типа.

Вторая половина это:

Если вывод аргумента не удался или специализация шаблона синтезированной функции будет неправильно сформирована, такая функция не будет добавлена ​​в набор функций-кандидатов для этого шаблона.

[температура выше]

Перевод: ошибка вывода типа приводит к отсутствию соответствующего кандидата в наборе перегрузки.

Примечание (примечания не являются нормативными) сформулировано несколько запутанно:

[Примечание 5: Если диагностика не требуется, программа по-прежнему некорректна. Проверка доступа осуществляется в рамках процесса замены. — последнее примечание]

Это происходит из CWG 1462. Целью этого изменения было прояснить, что ошибка вывода типа (и, следовательно, SFINAE) учитывает только диагностируемую неправильную форму.

Хороший ответ. ИМО, это как бы противоречит здравому смыслу, что замена на самом деле является частью дедукции (что означает, что неудача замены также является неудачей дедукции). Cppprefernece здесь кажется неправильным, поскольку в нем говорится, что замена происходит до/после вычета , тогда как в стандарте говорится, что она происходит в начале/конце вычета.

Daniel Langr 27.08.2024 23:39

Отлично, это была именно та цитата, которую я искал, и она действительно была в нужном разделе, не знаю, как я ее пропустил/не заметил :P Также спасибо за разъяснение примечания о том, что диагностика не требуется.

J L 28.08.2024 14:27

Другие вопросы по теме