Когда имя С++ «зависимо»? По-видимому, это не зависит, когда оно использует определение типа в той же области. Однако он зависим, когда использует определение типа во вложенной области это. Рассмотрим следующие примеры:
Пример А:
template <typename T>
struct some_struct
{
struct B
{
int b_;
};
T some_member_func();
T a_;
};
template <typename T>
T some_struct<T>::some_member_func()
{
using hello = B;
return a_;
}
.. отлично компилируется.
Пример Б (вложенный):
template <typename T>
struct some_struct
{
struct B
{
struct C {
int c_;
};
};
T some_member_func();
T a_;
};
template <typename T>
T some_struct<T>::some_member_func()
{
using hello = B::C;
return a_;
}
..выдает следующую ошибку:
<source>: In member function 'T some_struct<T>::some_member_func()':
<source>:365:19: error: need 'typename' before 'some_struct<T>::B::C' because 'some_struct<T>::B' is a dependent scope
365 | using hello = B::C;
| ^
| typename
Почему some_struct::B является зависимой областью видимости, а не some_struct (пример A)?
@n.1.8e9-где-мой-шарем. Интересно, потому что это имеет смысл, если оба работают с именем типа или без него, но не в сочетании. Почему some_struct<T> не является зависимой областью в С++ 11?
typename
не требуется (и не допускается) перед неквалифицированным идентификатором. тимсонг-cpp.github.io/cppwp/n3337/temp.res#3Связано/обман: Где и почему я должен помещать ключевые слова «шаблон» и «имя типа»?
Если я правильно понимаю https://en.cppreference.com/w/cpp/language/dependent_name, то и B
, и B::C
зависимы.
Но B
также «относится к текущему экземпляру», что позволяет использовать его без typename
. Кажется, это причудливый способ сказать, что «будь то тип, не может зависеть от специализации».
Вы можете специализировать B
, чтобы сделать B::C
не типом:
template <>
struct some_struct<int>::B
{
static void C() {}
};
(что интересно, частичная специализация не скомпилировалась)
Но вы не можете запретить B
быть типом с помощью специализаций.
Я не думаю, что вы можете частично специализировать членов. Вам нужно будет частично специализировать сам класс.
@user17732522 user17732522 Интересно, почему это так. Возможность специализировать элементы шаблонов, не являющиеся шаблонами, кажется довольно неясной для начала, интересно, почему это вообще разрешено.
Второй фрагмент в порядке с С++ 20,
typename
больше не нужен.