为什么使用模板的参数的类型成员作为函数的返回类型可以在没有 typname 关键字的情况下工作,但在其他地方却不起作用?

Mae*_*tro 2 c++ templates typename type-members

正如我们所知,我们必须typename在使用模板类型参数的类型成员之前进行perpend ,因为没有它,编译器不知道我们是访问类型成员还是使用静态数据成员,因为类模板的定义不是尚未存在(实例化)

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

到这里为止还可以,但是我发现了这个问题:

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;
}
Run Code Online (Sandbox Code Playgroud)

正如您在函数模板主体中所看到的,编译器抱怨缺少关键字,typename但将其用作返回类型却没有抱怨?有人可以解释为什么吗?

Bri*_*ian 5

您可能正在以 C++20 模式进行编译。带有 typenameDown!纸允许typename在某些情况下被省略。其中的一个背景是,当该类型名称是“一个DECL说明符的的DECL说明符-SEQ一的简单声明函数的定义在命名空间内”。在get_sum函数定义的情况下,(我假设)在命名空间范围内,decl-specifier-seqC_::value_type,由单个decl-specifier 组成,因此允许这个decl-specifier省略typename。此外,如果get_sum在类范围内定义,则成员声明将涵盖它要点,因此typename在这种情况下也不需要。

typename在大多数块范围声明中仍然需要,因为对于那些,依赖名称可能引用非类型;编译器假定它们是非类型的,除非typename使用,否则可能会导致错误。