Why using a template's parameter's type member as a return type of a function works without typname keyword but in other places it doesn't work?

Viewed 125

As we know we must perpend typename before using a Type Member of a Template Type Parameter because without it the compiler doesn't know whether we are accessing a Type member or using a static data member because the fact that the definition of the class template is not yet present (instantiation)

   template <typename T>
   void foo()
   {
       T::type x{}; // error: need a typename
       typename T::type y{}; // ok
   }

Until here it is OK but what about this problem I've discovered:

template <typename C_>
C_::value_type get_sum(C_ const& c) // no need to typename?!
{
    C_::value_type sum0{}; // errorL: need to typename keyword
    typename C_::value_type sum{};
    for(auto const& i : c)
        sum += i;
    return sum;
}

As you can see inside the function template body the compiler complains about missing the keyword typename but using it as a return type it doesn't complain? can someone explain why?

1 Answers

You are probably compiling in C++20 mode. The Down with typename! paper allows typename to be omitted in certain contexts. One of these contexts is when the type name is "a decl-specifier of the decl-specifier-seq of a simple-declaration or a function-definition in namespace scope". In the case of the get_sum function definition, which (I assume) is at namespace scope, the decl-specifier-seq is C_::value_type, consisting of a single decl-specifier, thus this decl-specifier is allowed to omit typename. Also, if get_sum were defined at class scope, it would be covered by the member-declaration bullet point, and thus typename would not be required in that case either.

typename continues to be required in most block-scope declarations, since for those, there is a possibility that the dependent name may refer to a non-type; the compiler presumes that they are non-types, possibly leading to an error, unless typename is used.

Related