C++ C++;:&引用;预期的&引用;在模板中的声明中
我在模板类的成员函数中遇到了以下问题:C++ C++;:&引用;预期的&引用;在模板中的声明中,c++,templates,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
#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;
}
#包括
使用std::map;
模板
C类{
公众:
B f(常数A&,常数B&)常数;
私人:
地图D;
};
模板
B C::f(常数A&A,常数B&B)常数{
常量迭代器x=D.find(a);
如果(x==D.end())
返回b;
其他的
返回x->秒;
}
当我让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
Bug.C:在成员函数“bc::f(const A&,const B&)const”中:
错误C:12:错误:应为“;”在“x”之前
Bug.C:13:错误:“x”未在此范围内声明
但是,当我创建类和函数的非模板版本时,a和B都是int,它编译时不会出现问题。这个错误有点让人迷惑,因为我无法想象它为什么需要一个“;”在“x”之前。您缺少一个
类型名
:
typename map<A,B>::const_iterator x = D.find(a);
typename map<A,B>::const_iterator x = D.find(a);
typename映射。这里需要typename
的原因是A
和B
是模板参数,这意味着的含义::const_迭代器
取决于A
和B
是什么。而对于人类来说,名称const_iterator
显然表明这是一种迭代器类型,而对于编译器来说,它不知道这是否是一种类型、数据成员等
在实例化模板之前,编译器将在第一次通过时进行语法检查,并通过添加typename
让编译器知道如何将map::const_迭代器作为类型进行分析
也有C++中的特殊规则(从链接问题中被羞耻地盗取):
模板声明或定义中使用的名称,即
假定依赖于模板参数不会命名类型,除非
适用的名称查找查找类型名称或名称为限定名称
通过关键字typename
如果您不添加typename
,编译器必须假设它不是类型您必须添加typename
:
typename map<A,B>::const_iterator x = D.find(a);
typename map<A,B>::const_iterator x = D.find(a);
typename映射::常量迭代器x=D.find(a);
说明:
typename
声明应将后面的名称视为类型。否则,名称将被解释为引用非类型。您错过了关键字,该关键字是引用类型并依赖于模板参数的限定名称之前所必需的:
typename map<A,B>::const_iterator x = D.find(a);
typename映射::常量迭代器x=D.find(a);
我领先你6秒。8v)答案很全面——我还发现问题中给出的错误信息具有误导性,这很有趣。C++编译器有时会被错误的错误消息所知,但是在我的机器G+4.7.2中,有一个更有用的<代码>错误:在STD之前需要“类型名称”::MAP::CONTRONTIORATER,因为“STD::MAP”是一个从属的范围< /C>你能以多快的速度让3个人发布3段相同的代码?我想知道他会选择哪一段是正确的one@HappyYellowFace希望有人打破了他们的任何约定,并更新解释。可能的重复BTW,命名C++源文件<代码> bug.c>代码>只是在自找麻烦。将来请告诉我们您的编译器版本。