[over.over] & para; 1 Функция с типом F
выбрана для типа функции FT
целевого типа, требуемого в контексте, если F
(после возможного применения преобразования указателя функции ( [conv.fctptr] )) идентично FT
.
[conv.fctptr] Значение типа "указатель на noexcept
функцию" может быть преобразовано в значение типа "указатель на функцию".
Это означает, что после выведения аргумента шаблона ( [over.over] & para; 2 ) для определения специализации функции шаблона, добавляемой к набору перегрузки, типы функции шаблона специализация и не шаблонная функция должны сравниваться с целевым типом, чтобы решить, какой из них следует «выбрать».
Разрыв связи для предпочтения не шаблонной функции ( & para; 4 ) вступает в силу только в том случае, если типы обеих функций соответствуют целевому типу (т. Е. Если выбрано более одной функции) ).
void(*)(int*)
и void(*)(int*)noexcept
- это два разных типа. Выражение приведения требует создания экземпляров спецификаций исключений обеих перегрузок, чтобы определить, какие из них соответствуют целевому типу приведения (т. Е. Какой из них должен быть выбран), тогда как выражение вызова требует только создания экземпляров спецификации исключений перегрузка, выбранная разрешением перегрузки.
Я полагаю, что Clang правильно потребовать создания экземпляра спецификации исключений специализации шаблона функции. Вполне вероятно, что GCC сначала проверяет, соответствует ли тип функции, не являющейся шаблоном, и, если это так, ему не нужно проверять тип специализации шаблона функции, зная, что, даже если он совпадает, прерыватель связи устранит это все равно. Возможно, это также соответствует, и стандарт здесь неоднозначен.