Это общая проблема для функций:
template <typename C>
void func(typename C::iterator i);
Теперь, если я позвоню func(int*)
, какое значение C
мне следует использовать?
В общем, вы не можете работать назад ! Многие различные C
могли бы определить внутренний тип iterator
, который для некоторого набора параметров оказывается int*
.
В вашем случае вы немного усложняете ситуацию:
template <typename T>
void func(typename Z<T>::ZZ const&);
Но по сути это та же проблема, Z<T>
- это шаблон, а не полный класс, и вы просите создать функцию для внутреннего типа ZZ
этого шаблона.
Предположим, я делаю:
template <typename T>
struct Z { typedef T ZZ; };
template <typename T>
struct Z<T const> { typedef T ZZ; };
Примечание: типично для итераторов, value_type
не является константным
Тогда, при вызове func(int)
, я должен использовать Z<int>
или Z<int const>
?
Не подлежит вычету.
И, таким образом, все это называется не выводимым контекстом , и Стандарт запрещает это, потому что нет разумного ответа.
Полезное правило: с подозрением относитесь к typename
в параметрах функции.
Примечание: они в порядке, если другой аргумент уже зафиксировал тип, например typename C::iterator find(C&, typename C::const_reference);
, поскольку, как только C
выводится, тогда C::const_reference
может использоваться без проблем