Ну, на самом деле, GCC принимает ваш код, но Clang не .Поэтому на первый взгляд неясно, является ли вызов неоднозначным.
Вы спрашиваете, какое правило разрешает неоднозначность в случае fun
;GCC, очевидно, считает, что такое правило существует.Я полагаю, что правило, которое применяет GCC, это правило [over.match.best] /1.7, которое предпочитает более специализированный шаблон функции по сравнению с менее специализированным.
Процедура определения того, какойШаблон функции более специализирован, чем другой, описанный в [temp.func.order] и подробно объясненный в этом ответе SO .Однако вы заметите, что при попытке применить эту процедуру к двум перегрузкам fun
, как в этом вопросе, мы сталкиваемся с проблемой, что уникальный синтезированный тип, который должен быть заменен на U
в первой перегрузке, будет нуждатьсяиметь элемент с именем sth
, и природа этого члена не указана, и хотя человеку может быть ясно, что удержание при второй перегрузке fun
должно завершиться успешно независимо от типа sth
,возможно, компилятор не сможет это доказать.
Это CWG 1157 .Поскольку этот вопрос все еще остается открытым без предлагаемого решения, у меня нет понимания, намеревается ли WG21 добиться успеха в решении по этой перегрузке.