我想请求正确的语法帮助声明一个std :: map,其mapped_type是模板类的内部类。
请在下面的代码中找到#if /#else块。 “#if 1”块具有包含内部类Inner的模板类Outer。外部定义了函数Func,它采用了一个std映射,其mapped_type的类型是Inner。
#include <map>
#if 1
template<typename C, typename T>
class Outer
{
public:
Outer(const C& c, const T& t){}
virtual ~Outer(){}
class Inner
{
public:
Inner(){}
Inner(T t){}
virtual ~Inner(){}
protected:
T mT;
};
void Func(std::map<C, Inner>& rMap);
protected:
std::map<C, Inner> mMap;
};
template<typename C, typename T>
void Outer<C, T>::Func(std::map<C, Outer::Inner>& rMap)
{
std::map<C, Inner>::iterator iter;
for (iter = rMap.begin(); iter != rMap.end(); ++iter)
{
mMap[iter->first] = iter->second;
}
}
#else
class Outer
{
public:
Outer(const int& i, const double& d){}
virtual ~Outer(){}
class Inner
{
public:
Inner() : mD(0){}
Inner(const double d) : mD(d){}
virtual ~Inner(){}
protected:
double mD;
};
void Func(std::map<int, Inner>& rMap);
protected:
std::map<int, Inner> mMap;
};
void Outer::Func(std::map<int, Inner>& rMap)
{
std::map<int, Inner>::iterator iter;
for (iter = rMap.begin(); iter != rMap.end(); ++iter)
{
mMap[iter->first] = iter->second;
}
}
#endif
int main()
{
return 0;
}
在std :: map迭代器的声明中,Outer :: Func(...)中的编译失败,即此行:
std::map<C, Inner>::iterator iter;
我已经尝试但无法弄清楚代码行有什么问题。
对于比较/对比,“#else”块包含类似性质的非模板代码。这段代码编译。
编译错误和g ++版本是:
>g++ main.cpp
main.cpp: In member function ‘void Outer<C, T>::Func(std::map<C, Outer<C, T>::Inner, std::less<_Key>, std::allocator<std::pair<const C, Outer<C, T>::Inner> > >&)’:
main.cpp:31: error: expected ‘;’ before ‘iter’
main.cpp:33: error: ‘iter’ was not declared in this scope
>g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
感谢您的帮助。
答案 0 :(得分:9)
由于Inner
是您的模板Owner<C, T>
的成员,因此它变为dependent name。这会导致标识符iterator
(在这种情况下是std::map<C, Inner>
的成员)成为依赖名称。
这会强制您根据规则使用关键字typename
:
typename std::map<C, Inner>::iterator iter;
~~~^~~~~
这是因为编译器无法确定类内部的某些结构是什么意思,因为它还不知道C
和T
使用的确切类型:
在模板定义(类模板和函数模板)中,某些构造的含义可能因实例而异。特别是,类型和表达式可能取决于类型模板参数的类型和非类型模板参数的值。
typename
关键字用于告诉编译器您正在访问的符号确实是类型别名/类型。