75

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

Jake Schmidt
  • 1,558
  • 9
  • 16
  • 3
    I'm a bit surprised that the standard would find it ambiguous (hence, requiring `typename`), since (I think...) it *has* to be a type there. Might want to add `language-lawyer` tag. – Eljay May 24 '20 at 19:05
  • 7
    C++20 allows to remove some typename usage. – Jarod42 May 24 '20 at 19:11
  • 3
    @Eljay It still needs to know that it _is_ a type ;) It being a type is part of how "there" is defined/recognised. Or, rather, it used to. – Asteroids With Wings May 26 '20 at 13:30

2 Answers2

72

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.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • 8
    IIRC we made `typename` _optional_ already in C++11 for the base-specifiers and mem-initializer-ids. The original `typename` proposal disallowed it everywhere it wasn't required, but we believed it would be harmless to accept a redundant `typename`. – MSalters May 25 '20 at 09:46
21

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

Community
  • 1
  • 1
cigien
  • 57,834
  • 11
  • 73
  • 112