struct A{};
template <typename T>
struct B
{
typename ::A a1; //(1)
typename A a2; //(2): error
};
int main(){return 0;}
Why is the first case correct, but the second isn't? I don't understand the meaning of that restriction.
And anyway, why is the first case allowed? ::A
isn't template-parameter dependent name. What's meaning in it?
The rule isn't that you can only use typename
if the type is nested in a dependent scope. The rules are, more or less:
typename
if it's in a dependent scopetypename
where it's allowed by the grammar.The grammar allows it for a subset of qualified-id, specified by
typename-specifier:
typename nested-name-specifier identifier
typename nested-name-specifier template<opt> simple-template-id
nested-name-specifier:
:: (C++14 or later)
::<opt> type-name ::
::<opt> namespace-name ::
decltype-specifier ::
nested-name-specifier identifier ::
nested-name-specifier template<opt> simple-template-id ::
So the second case is certainly forbidden, since it doesn't involve any nesting. Strictly speaking, before C++14, the first was also forbidden, since a global qualifier ::
didn't match that grammar.
As @MikeSeymour's answer explains, going strictly by the standard (C++11, I don't have a C++14 text on hand), case (1) should actually be erroneous as well - typename
prefixing a qualified name can only be used when there's at least one name on the left-hand side of the ::
.
However, as pointed out by @hvd in the comments, CWG issue 382 indicates the actual intent is to allow typename
before any qualified name, including global-namespace qualification. Since this is what most compilers seem to implement, the rest of this answer follows with this idea.
When viewed like this, it's not that case (2) is a restriction, it's that case (1) is benevolence. The required rule (and its very original wording, I believe) is basically that "if a qualified name which depends on template parameters denotes a type, you must prefix it with typename
." For convenience, it is loosened to "typename
can be used for any qualified name which dentoes a type, whether it's dependent or not."(1)
In contrast, an unqualified name can never be ambiguous as to whether it refers to a type or not, so it never requires typename
and typename
is therefore not allowed there.
(1)This loosening is not really explicitly stated in the standard, but follows from the combination of several rules. Basically, wherever a simple-type-specifier (something which denotes a type) is allowed, the grammar also allows a typename-specifier (a qualified name prefixed with typename
). The rules for templates (mainly in 14.6) only state that typename
is required when a dependent qualified name denotes a type. Since nothing forbids typename
in other contexts, it can be used with any qualified name which denotes a type (even outside of template context).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With