class A
{
static int iterator;
class iterator
{
[...]
};
[...]
};
Run Code Online (Sandbox Code Playgroud)
我(我想)理解为什么typename需要这里:
template <class T>
void foo() {
typename T::iterator* iter;
[...]
}
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么typename不需要这里:
void foo() {
A::iterator* iter;
[...]
}
Run Code Online (Sandbox Code Playgroud)
谁能解释一下?
编译器之所以没有后者的问题,我发现在评论中得到了很好的回答:
在A::iterator我的情况下,我不明白为什么编译器不会混淆它static int iterator? - xcrypt
@xcrypt因为它知道两者A::iterator是什么,并且可以根据它的使用方式选择哪一个 - Seth Carnegie
typename我认为编译器在合格的从属名称之前需要的原因在Kerrek SB接受的答案中得到了很好的回答.请务必阅读有关该答案的评论,尤其是iammilind的评论:
"T :: A*x ;,对于T :: A是一个类型且T :: A是一个值的情况,这个表达式都可以为真.如果A是一个类型,那么它将导致指针声明;如果A是一个值,然后它将导致乘法.因此,单个模板对于2种不同类型将具有不同的含义,这是不可接受的."
我正在尝试编写一个函数来打印常见STL容器(向量,列表等)的表示.我给函数一个模板参数T,例如,它可能代表向量.我在获取类型为T的迭代器时遇到问题
vector<int> v(10, 0);
repr< vector<int> >(v);
Run Code Online (Sandbox Code Playgroud)
...
template <typename T>
void repr(const T & v)
{
cout << "[";
if (!v.empty())
{
cout << ' ';
T::iterator i;
for (i = v.begin();
i != v.end()-1;
++i)
{
cout << *i << ", ";
}
cout << *(++i) << ' ';
}
cout << "]\n";
}
Run Code Online (Sandbox Code Playgroud)
...
brett@brett-laptop:~/Desktop/stl$ g++ -Wall main.cpp
main.cpp: In function ‘void repr(const T&)’:
main.cpp:13: error: expected ‘;’ before ‘i’
main.cpp:14: error: ‘i’ was not declared in …Run Code Online (Sandbox Code Playgroud) 在前一段时间处理一些图形代码时,我使用int作为底层坐标持有者编写了Rect和Region类,并且工作正常.Region实现为STL列表的简单类扩展,只包含一个Rects列表.
现在我还需要使用双精度作为底层坐标持有者的同类课程,并决定尝试将其模板化.所以我基本上以"智能方式"将"int"替换为"typename T"并修复了问题.
但是还有一个问题让我难过.我想通过在构成它的所有Rect上进行并集来计算Region的边界框.在没有模板化的情况下工作正常,但是当它被模板化时,g ++会在列表迭代器上产生扼流圈.
这是相关的代码:
// Rect class that always remains normalized
template <typename T>
class KRect
{
public:
// Ctors
KRect(void)
: _l(0), _t(0), _r(0), _b(0)
{
}
void unionRect(const KRect& r)
{
...
}
private:
T _l, _t, _r, _b;
};
// Region class - this is very brain-dead
template <typename T>
class KRegion : public std::list< KRect<T> >
{
public:
...
// Accessors
KRect<T> boundingBox(void)
{
KRect<T> r;
iterator i;
for (i = this->begin(); i != …Run Code Online (Sandbox Code Playgroud)