When is a C name "dependent"? Apparently it is not dependent when it uses a type-definition in the same scope. It is however dependent, when it uses a type definition in a nested scope of this scope. Consider the following examples:
Example A:
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_;
}
.. compiles fine.
Example B (Nested):
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_;
}
..issues the following error:
<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
Why is some_struct::B a dependent scope but not some_struct (example A)?
CodePudding user response:
If I'm reading https://en.cppreference.com/w/cpp/language/dependent_name correctly, both B
and B::C
are dependent.
But B
also "refers to the current instantiation", which allows it to be used without typename
. It seems to be a fancy way of saying that "whether it's a type can't be affected by specializations".
You can specialize B
to make B::C
not a type:
template <>
struct some_struct<int>::B
{
static void C() {}
};
(interestingly, a partial specialization didn't compile)
But you can't prevent B
from being a type via specializations.