Ответ 1
Что касается примера в OP: как было указано мной W.F., здесь важно, что это член шаблоны функций. Вы добавили декларацию using, которая указывает ([namespace.udecl]/15):
Когда декларация using приносит имена из базового класса в производную класс, функции-члены и шаблоны функций-членов в производный класс переопределяет и/или скрывает функции-члены и член функциональные шаблоны с тем же именем, список параметров-параметров, cv-qualification и ref-qualifier (если есть) в базе класс (а не конфликтующий).
Обратите внимание, что параметры шаблона не учитываются. И именно Кланг корректно обрабатывал код, скрывая версию int
.
С другой стороны, если вы посмотрите пример tobi303, предложите под своим сообщением, GCC в порядке. Это просто не указано, чтобы как-то быть разрешено.
Во-первых, [temp.fct.spec]/3:
Трейлинг аргументов шаблона, которые можно вывести или полученные из шаблона-аргумента по умолчанию, могут быть опущены из списка явных шаблонных аргументов. [...] В контекстах, где вычет выполняются и не выполняются, или в ситуациях, когда вычет не производится, если список аргументов шаблона указан и он, наряду с любым значением по умолчанию аргументы шаблона, определяет шаблон одной функции специализации, то идентификатор шаблона является lvalue для функции специализированная специализация.
Текст, выделенный полужирным шрифтом, указывает, что ваша программа хорошо сформирована, только если аргумент шаблона, который мы даем, назначает одну специализацию. И, якобы, это не так, поскольку согласно [temp.arg.nontype]/1:
Аргумент шаблона для непигового шаблона-шаблона без шаблона должен быть одним из:
- для нетипового шаблона-параметра интегрального или перечисляемого типа, преобразованное константное выражение типа Шаблон-параметры;
И 0 подходит для обеих перегрузок как преобразованное константное выражение. Из-за того, что для аргументов шаблона не было никакого рейтинга ICS, это неоднозначно.