Reputation: 42235
According to https://stackoverflow.com/a/61991146/508343:
One of the new features in C++20 is Down with typename.
In C++17, you had to provide the typename keyword in nearly all† dependent contexts to disambiguate a type from a value. But in C++20, this rule is relaxed a lot. In all contexts where you need to have a type, the typename keyword is no longer mandatory.
template<typename T>
concept IsOK = true;
template<typename T>
requires IsOK<T::U> // error: use ‘typename T::U’
void f()
{}
struct A
{
using U = int;
};
int main()
{
f<A>();
}
In the code above, obviously, IsOK
concept can take types only.
Why is typename
required here?
See online demo
Upvotes: 3
Views: 743
Reputation: 473272
The answer is speaking loosely about what "context" means. What the feature is doing is finding places where it is grammatically impossible for anything other than a typename to appear in that location. It is those places where typename
is no longer necessary.
For example, using name = X;
. Grammatically, this is a type alias declaration. As such, whatever X
is, the grammar requires that it be a type. If the X
happens to be a name dependent on a template parameter, whatever that name is must be a type. So the grammar is unambiguous, and typename
is redundant.
The syntax name<X>
states that X
is a template argument to the template name
. But template arguments do not have to be types. A specific template may take a type as a specific argument, but grammatically, X
could be an identifier referencing a variable or a template. Therefore, you must disambiguate ambiguous dependent X
s.
Upvotes: 13