Рассмотрим следующий пример:Шаблон видимость псевдонима в вложенного класса
template<typename X>
struct Z {};
struct A
{
using Z = ::Z<int>;
struct B : Z
{
using C = Z;
};
};
Это нормально компилируется. Ницца. Но теперь добавить еще один параметр в Z
:
template<typename X, typename Y>
struct Z {};
struct A
{
template<typename X>
using Z = ::Z<X, int>;
struct B : Z<B>
{
using C = Z<B>; // error: too few template arguments for class template 'Z'
};
};
Хорошо, может быть, имеет смысл, что определение шаблона псевдонима Z
в классе A
виден при выводе вложенного класса B
, но не внутри ее тела, вызывая погрешность, поскольку глобальное определение Z
имеет два параметра.
Но почему это поведение отличается в первом случае, когда Z
просто тип псевдонима в A
?
Наконец, сделать A
шаблон:
template<typename X, typename Y>
struct Z {};
template<typename T>
struct A
{
template<typename X>
using Z = ::Z<X, int>;
struct B : Z<B>
{
using C = Z<B>;
};
};
Теперь больше нет ошибки. Почему?
(Проверено на Clang 3.6 и GCC 4.9.2)
Ничего себе. Это совершенно понятно, спасибо. Ошибка на самом деле появилась, когда 'A' перестает быть шаблоном, который, как я думал, упростит код. Однако теперь я вынужден использовать два разных имени для двух 'Z', что делает код более уродливым. Если есть лучший способ обхода проблемы, пожалуйста, дайте мне знать. – iavr
@iavr Как насчет 'использования C = Z;'? (Не будет работать для 'A', являющегося шаблоном) – Columbo
Теперь это впечатляет :-) Да, он работает на этом упрощенном коде здесь, но не на моем оригинальном (« неизвестное имя типа «Z'')». Я должен проверить, где разница. 'A' больше не является шаблоном, и я намерен сохранить его таким образом. – iavr