为什么我们需要这里的typename?

15 c++

template<class T>
class Set 
{
public:
   void insert(const T& item);
   void remove(const T& item);
private:
   std::list<T> rep;
}

template<typename T>
void Set<T>::remove(const T& item)
{
   typename std::list<T>::iterator it =  // question here
    std::find(rep.begin(),rep.end(),itme);
   if(it!=rep.end()) rep.erase(it);

}   
Run Code Online (Sandbox Code Playgroud)

为什么需要remove()中的typename?

Ale*_*lli 21

一般来说,C++需要typename因为它从C继承的不幸语法[*],如果没有非本地信息就不能说 - 例如 - 在名称A * B;是否A为类型(在这种情况下,这是一个声明B为是否指向它(在这种情况下,这是一个乘法表达式 - 很可能,因为A,如果没有非本地信息,你可以告诉所有人,可能是一个重载operator*做一些奇怪事情的类的实例;-).

在大多数情况下,编译器确实具有消除歧义所需的非本地信息(尽管不幸的语法仍然意味着低级解析器需要来自保留符号表信息的更高级别层的反馈)...但是使用模板它不会(一般情况下,虽然在这种特殊情况下,专业化技术上可能是非法的,std::list<T>因此它::iterator不是类型名称;-).

[*]不仅仅是我的观点,还有Ken Thompson和Rob Pikes的观点,目前我的同事们正在忙于设计和实现一种新的内部使用的编程语言:新的编程语言,而它的语法大部分都是C语言的,不重复C的语法设计错误 - 它是新语言(例如在古老的Pascal中),语法足以区分必须命名类型的标识符和不能标记类型的标识符;-).

  • 迭代器可能是静态成员变量。默认情况下,这是编译器假设的。因此编译器错误。 (3认同)
  • 很抱歉让这件事起死回生,但 8 年后我很好奇是否有任何关于该编程语言的更多信息可以透露。虽然我没有屏住呼吸。 (2认同)

aJ.*_*aJ. 12

如果您正在谈论typename用于std::list<T>::iterator:

typename用于阐明这iterator是在类中定义的类型std::list<T>.没有typename,std::list<T>::iterator将被视为静态成员.typename每当依赖于模板参数的名称是类型时使用.