我创建了一个继承std::map
的类,并尝试使用一种方法来获取特定索引处的值。
#define MYAPI_EXPORTS
#ifdef MYAPI_EXPORTS
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
template<class _Value>
class MY_API MyDictionary : public std::map<std::string, _Value>
{
_Value GetItem(int index)
{
std::map<std::string, _Value>::iterator itr = this->begin(); //compile error at this line
int c = 0;
while (c < index)
{
itr++;
c++;
}
return itr->second;
}
};
'std :: map :: iterator itr'此行在编译时显示错误。
错误是
error C2760: syntax error: unexpected token 'identifier', expected ';'
error C7510: 'iterator': use of dependent type name must be prefixed with 'typename'
似乎迭代器类型未在编译时定义。有解决此问题的解决方案吗?
答案 0 :(得分:4)
您可以通过以下方式对其进行修复:
typename std::map<std::string, _Value>::iterator itr = this->begin();
或
auto itr = this->begin();
答案 1 :(得分:1)
要解决此错误,您可以按照编译器给出的提示进行操作,也可以将行更改为
auto itr = this->begin();
虽然过度使用auto
是有问题的,但对于迭代器类型通常认为是可以的; begin()
和end()
成员函数的返回类型很常见(有时很复杂),足以不键入确切的类型。
进一步的说明:GetItem
也可以使用const_iterator
,因此auto itr = this->cbegin();
会有所改进。
答案 2 :(得分:1)
错误消息告诉您确切的操作:
typename std::map<std::string, _Value>::iterator itr = this->begin();
// ^^^^^^^^^
…但是不是为什么要这么做。
简而言之,这是与模板和所谓的“从属名称”有关的C ++古怪。因为_Value
是模板参数,并且因为存在模板专门化,所以C ++在解析过程中稍后才能确定std::map<std::string, _Value>
的成员类型为iterator
。因此,您的声明格式错误,因为即使斜眼了看,编译器也无法将其视为声明。 typename
说“我保证这将是一种类型”,然后一切都很好(只要它确实是一种类型!)。
您可能认为这应该是C ++的问题,而不是您的问题,您可能是对的,但这就是事实。您可以搜索有关此的更多信息,也可以认为当编译器告诉您编写typename
时,您编写typename
就是理所当然的。
或者,使用auto
代替,使您的代码更好,并同时解决问题:
auto itr = this->begin();
顺便说一句,您的代码表明您使用了错误的容器,GetItem
应该是const
,应该使用cbegin()
而不是begin()
(尽管这是如果您遵循const
的建议,这已经为您完成了工作,并且std::advance
已经存在……