我一直在教自己C ++,并发现了一件有趣的事情。
最明显的迭代器形式是指针。
所以,我曾经认为迭代器对象的工作方式与指针几乎相同(例如int *i
);
但是,现在我想,将迭代器对象称为指针(如int **i
)而不是指针(int *i
)会更准确。
当我编写下面的代码时,我注意到了这一点。
set<Point*, Point> points; //This class encapsulates x and y coordinates for a 2 dimensional point
set<Point*, Point>::iterator it;
int x = 22;
int y = 4;
Point* pt = new Point(x, y);
points.insert(pt);
//Similar statements are here, to insert other Point objects with different arguments
for (it = points.begin(); it != points.end(); it++) {
cout << "**it: " << **it << ", *it :" << *it << ", Address : " << &it << endl;
}
结果,
**it
显示了Pointer类对象的值
*it
显示地址
&it
显示了it
对象的地址
那么,说迭代器对象(it
)与**it
基本相同是不对的?
另一个与迭代器有点不同的问题:
如果我需要创建一组类对象,例如:set<ClassName*, ClassName> SetName;
,那么正确的方法是什么? (只要此类包含可比较的数据类型,例如int
或double
)
如果您提供一些建议,我将不胜感激。
答案 0 :(得分:3)
这是一个错误的假设。在您的示例中,集合的value_type
是指针Point *
。 *it
为您提供了一个集合中的元素,该元素是对此value_type
的某个对象的引用,其类型为Point *
,而++it
“指向”下一个元素集合。因此迭代器的行为与指向value_type
的对象的指针的行为方式相同。
当您使用**it
之类的表达式时,第二个取消引用不会应用于迭代器。它应用于集合中的对象。您可以通过以下方式设想表达式**it
Point *pp = *it;
Point p = *pp;
容器的迭代器负责为您提供对容器元素的访问。因此,如果容器中的元素具有类型value_type
,则迭代器提供对此value_type的这些元素的访问。反过来,元素可以是指向对象的指针,甚至是指向对象指针的指针等等。
至于你的第二个问题,那么如果类具有相应的运算符函数并且类本身有一些简单的默认构造函数,那么你可以使用这样的方法虽然最好定义一个分离比较器或者只是定义{{1对于类的对象。在最后一种情况下,你可以写
operator <
没有明确的第二个模板参数。
以下是您的方法的示范程序
std::set<Point> s;
程序输出
#include <iostream>
#include <set>
int main()
{
struct Point
{
int x, y;
bool operator ()( const Point &p1, const Point &p2 ) const
{
return p1.x < p2.x && p1.y < p2.y;
}
};
std::set<Point, Point> s;
s.insert( { 2, 2 } );
s.insert( { 1, 1 } );
for ( const Point &p : s ) std::cout << p.x << ' ' << p.y << std::endl;
return 0;
}