C ++:“期待;”在模板中的声明

时间:2013-08-09 21:00:08

标签: c++ templates

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

#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'之前。

3 个答案:

答案 0 :(得分:12)

您错过了typename

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

请阅读Where and why do I have to put the “template” and “typename” keywords?。您需要typename的原因是因为AB是模板参数,这意味着::const_iterator 的含义取决于 {{1} }和A是。对于人类而言,名称B使得显然这是一个迭代器类型,对于编译器而言,它不知道这是一个类型,数据成员等。

编译器将在实例化模板之前对第一遍进行语法检查,并添加const_iterator,让编译器知道将typename解析为类型。

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

  

模板声明或定义中使用的名称,即   取决于模板参数,假定不命名类型,除非   适用的名称查找查找类型名称或名称是合格的   通过关键字typename。

如果您不添加map<A,B>::const_iterator,编译器必须假定它不是类型

答案 1 :(得分:2)

您错过了关键字typename,这是在引用类型且取决于模板参数的限定名称之前所必需的:

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

答案 2 :(得分:1)

您必须添加typename

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

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