Spec considers *typename* can be dropped when there is no ambiguous of regarding identifier as type. And example(https://timsong-cpp.github.io/cppwp/temp.res#general-example-5) shows this OK. template<class T> T::R f();//OK, return type of a function declaration at global scope However, all compilers including GCC, clang, MSVC++ complains missing typename because error: need ‘typename’ before ‘T::R’ because ‘T’ is a dependent scope 1 | template<class T> T::R f(); | ^ | typename Here I quote spec(https://timsong-cpp.github.io/cppwp/temp.res#general-4.1): A qualified or unqualified name is said to be in a type-only context if it is the terminal name of a typename-specifier, nested-name-specifier, elaborated-type-specifier, class-or-decltype ... I understand this relaxation of enforcing *typename* is not so critical. Still it is nice to strictly follow spec.
You need to use -std=c++20.
Thank you and my apology.