This bit of code compiled in C++20 (using gcc 10.1) without using the typename
keyword before the dependent type std::vector<T>::iterator
. Why does it compile?
#include <vector> template<typename T> std::vector<T>::iterator // Why does this not require "typename" before it? f() { return {}; } int main() { auto fptr = &f<int>; }
code playground
The typename keyword is needed whenever a type name depends on a template parameter, (so the compiler can 'know' the semantics of an identifier (type or value) without having a full symbol table at the first pass).
" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.
typename is needed in your declaration of 'it' because otherwise the compiler doesn't know that it's a type declaration rather than an expression. According to this page, "Use the keyword typename if you have a qualified name that refers to a type and depends on a template parameter."
C++ adds two new keywords to support templates: 'template' and 'typename'. The second keyword can always be replaced by the keyword 'class'.
Now, it’s not “before a dependent type”: The typename disambiguator was only ever required before a qualified type name whose qualifier is dependent. For example: Without the typename the statement there would be a multiplication instead of a pointer declaration (and it is still needed in C++20). There were already some contexts whe
My paper “ Down with typename! ” (co-authored with my friend Nina Ranns) identifies those contexts and provides the wording changes that were needed to make the relaxed rules part of the forthcoming C++20 standard. Because C++20 has relaxed the rules.
(since C++20) The semiregular concept specifies that a type is both copyable and default constructible. It is satisfied by types that behave similarly to built-in types like int, except that they need not support comparison with == .
Every one of them says something like "knowing C is a prerequisite for understanding C++" or "C++ is an extension of C". This is a clear indicator that they do not understand C++ as well as they believe they do. Here's the thing... to really understand C++, you have to understand the machine code it generates.
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.
One such context is the return type of a function in class scope, as in your example. Others include the type in a member declaration, the type on the right-hand side of a using declaration, the parameter declaration of a lambda, the type you're passing to static_cast
, etc. See the paper for the full list.
† Nearly all because base-specifiers and mem-initializer-ids were always excluded, as in:
template <typename T> struct X : T::type { }; // always ok
This is okay because, well, that needs to be a type. The paper simply extends this logic (well, it has to be a type, so let's just assume it's a type) to a lot more places that have to be types.
From the reference, from c++20, in contexts where the dependent name is unambiguously a typename, the typename
keyword is no longer needed. In particular:
A qualified name that is used as a declaration specifier in the (top-level) decl-specifier-seq of:
a simple declaration or function definition at namespace scope
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