为什么我不能使用 const_iterator 调用模板基类构造函数?

4
由于某些原因,以下代码会出现错误 符号“TemplateBase”无法解析:
template <typename T>
class TemplateBase
{
    TemplateBase(std::map<std::string, T>::const_iterator anIterator)
    { }
};

class SubClass : public TemplateBase<int>
{
    SubClass(std::map<std::string, int>::const_iterator anIterator) :
        TemplateBase<int>(anIterator) //Error: Symbol 'TemplateBase' could not be resolved.
    { }
};

奇怪的是,当我删除::const_iterator,只保留std::map<std::string, int>时,没有出现错误:

template <typename T>
class TemplateBase
{
    TemplateBase(std::map<std::string, T> aMap)
    { }
};

class SubClass : public TemplateBase<int>
{
    SubClass(std::map<std::string, int> aMap) :
        TemplateBase<int>(aMap) //No error.
    { }
};

另外,以下函数也不会导致错误,所以似乎与模板基类调用和const_iterator的组合有关:
void function()
{
    std::map<std::string, int>::const_iterator anIterator;
    TemplateBase<int> aTemplateBase(anIterator); //No error
}

有没有什么规定禁止在基类模板构造函数中使用const_iterator作为参数?或者这是编译器的bug吗?
我使用C++11,在Windows 7上使用MinGW 64位4.9.0进行编译。

8
你缺少了 typename - ildjarn
1
“错误”?哪一个? - lgvidal
@Igvidal:“错误:无法解析符号'TemplateBase'”,它出现在代码片段的注释中。我现在已将其添加到主文本中。 - Aberrant
@ildjarn:当<class T>被替换为<typename T>时,问题仍然存在。此外,在我的实际代码中,我正在使用一个类。我已经编辑了问题的代码。 - Aberrant
3
不仅可能,而且必须!;-D - ildjarn
显示剩余2条评论
1个回答

6

当您使用依赖于模板类型的嵌套类型时,需要使用 typename 关键字:

TemplateBase(typename std::map<std::string, T>::const_iterator anIterator)
{ }

哦,没想到在那里放置typename甚至是合法的。这个解决了我的问题,谢谢。但是为什么对于std::map<std::string, T>::const_iterator而言是必要的,而对于std::map<std::string, T>则不是呢? - Aberrant
2
@Aberrant 因为在第二种情况下你没有引用嵌套类型。另外,你觉得这个是你问题的重复吗?我的关闭投票是有约束力的,所以在我这样做之前我想先确认一下。 - Praetorian
@Praetorian 我想这很可能是的。我在那里找不到这个特定的语法 (ClassName(typename someComplexlyDerivedNestedIdontevenType)),但根据关键字的详细说明,它可能以某种方式存在于其中。我会确保彻底阅读整个内容。所以,关闭这个问题是可以的,我想。 - Aberrant
没有 typename 关键字,编译器无法确定 const_iterator 是类型名还是变量名。之后您可以编写一个模板特化的 std::map,以更改该细节。 - M.M
@Aberrant:有关typename的更多信息,请参阅此FAQ:什么是模板中使用的typename关键字? - ildjarn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接