C++:在模板中的声明中"expected ;"

C++: "expected ;" in declaration in template

本文关键字:expected 声明 C++      更新时间:2023-10-16

我在模板类的成员函数中遇到了以下问题:

#include <map>
using std::map;
template <typename A,typename B>
class C {
  public:
    B f(const A&,const B&) const;
  private:
    map<A,B> D;
};
template <typename A,typename B>
B C<A,B>::f(const A&a,const B&b) const {
   map<A,B>::const_iterator x = D.find(a);
   if(x == D.end())
     return b;
   else
     return x->second;
}

当我有g++编译时,我得到以下错误:

Bug.C: In member function 'B C<A,B>::f(const A&, const B&) const':
Bug.C:12: error:expected ';' before 'x'
Bug.C:13: error: 'x' was not declared in this scope

然而,当我制作类和函数的非模板化版本时,a和B都是int,它编译起来没有问题。这个错误有点令人费解,因为我无法想象它为什么想要一个";"在"x"之前。

您缺少一个typename:

typename map<A,B>::const_iterator x = D.find(a);

请阅读我为什么要把"模板"answers"typename"关键字放在哪里?。这里需要typename的原因是AB是模板参数,这意味着::const_iterator的含义取决于AB是什么。对于一个人来说,const_iterator这个名字很明显表明这是一个迭代器类型,而对于编译器来说,它不知道这是一种类型、数据成员等。

在实例化模板之前,编译器将在第一次通过时进行语法检查,通过添加typename,可以让编译器知道将map<A,B>::const_iterator解析为类型。

此外,C++中还有一条特殊规则(可耻地从关联问题中窃取):

模板声明或定义中使用的名称依赖于模板的参数被假定为不命名类型,除非适用的名称查找查找类型名称或该名称是限定的通过关键字typename。

如果不添加typename,编译器必须假设它不是类型。

您错过了关键字typename,它在引用类型并依赖于模板参数的限定名称之前是必需的:

typename map<A,B>::const_iterator x = D.find(a);

您必须添加typename:

typename map<A,B>::const_iterator x = D.find(a);

说明:
typename指出,后面的名称应被视为一种类型。否则,名称将被解释为引用非类型。