Рассмотрим пример:
#include <iostream>
#include <vector>
template <class, class T>
using alias = T;
template <template <class...> class>
struct tt_wrapper{};
template <class...>
struct t_wrapper{};
struct A {
template <template <class...> class TT, class T>
void foo(alias<tt_wrapper<TT>, T>) { std::cout << "A::foo invoked" << std::endl; }
};
struct B: A {
using A::foo;
template <class U, class T>
void foo(alias<t_wrapper<U>, T>) { std::cout << "B::foo invoked" << std::endl; }
};
int main() {
B b;
b.foo<std::vector>(int{});
}
В соответствии с [Namespace.udecl] / 15:
Когда объявление использования переносит имена из базового класса в производный
область действия класса, функции-члены и шаблоны функций-членов в
переопределение и / или скрытие производного класса функции-члены и член
шаблоны функций с тем же именем, параметр-тип-список,
cv-квалификация и ref-квалификатор (если есть) в базовом классе (скорее
чем противоречивый).
Таким образом, очевидно, что параметры шаблона не должны участвовать в сокрытии функций-членов. Однако в нашем примере параметры шаблона передаются в подпись с использованием псевдонима. тем не менее лязг не похоже на то, что псевдоним является частью функции Параметр типа-лист и утверждая:
prog.cc:26:7: error: no matching member function for call to 'foo'
b.foo<std::vector>(int{});
~~^~~~~~~~~~~~~~~~
prog.cc:21:10: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'U'
void foo(alias<t_wrapper<U>, T>) { std::cout << "B::foo invoked" << std::endl; }
^
1 error generated.
Я намеренно пропустил gcc, поскольку он включает список параметров шаблона в процессе сокрытия. Прав ли лязг?
A::foo
а также B::foo
имеет
foo
)T
!!!)const
не летучий)Список параметров шаблона не учитывается.
Метод в базовом классе не является виртуальным, поэтому скрывается и не переопределяется.
демонстрация того факта, что список параметров типа T
,
Других решений пока нет …