Normally, typename
is used to disambiguate between cases where an identifier may refer to a type, or may refer to something else:
template
From cppreference
Usage:
- In a template declaration, typename can be used as an alternative to class to declare type template parameters and template template parameters (since C++17).
- Inside a declaration or a definition of a template, typename can be used to declare that a dependent name is a type.
- Inside a requirements for type requirements (since C++20)
So I would say that you have no guaranties that case 1 and case 2 will compile. As they do not fall into any of these three usage cases.
And for case 3, let's see what cppreference has to say about that:
The keyword
typename
may only be used in this way before qualified names (e.g. T::x), but the names need not be dependent.The keyword typename must only be used in template declarations and definitions and only in contexts in which dependent names can be used. This excludes explicit specialization declarations and explicit instantiation declarations.(until C++11)
The keyword typename can be used even outside of templates. (since C++11)
So as there is no template in your example, case 3 should be guarantied to work only since C++11
And indeed a test program compiled OK with g++ -std=c++11 but issued this warning without -std=c++11
warning: 'typename' occurs outside of a template [-Wc++11-extensions]