先来问初始化一个容器
std::map<uint32_t, std::string> namelist;
auto ret_pr = namelist.insert(std::make_pair(1, "1111"));
namelist.insert(ret_pr.first, std::make_pair (2, "2222"));
namelist[3] = "3333";
下面我们通过两种方式来遍历这个容器,如下所示:
//方法一:
for (std::map<uint32_t, std::string>::iterator iter = namelist.begin(); iter != namelist.end(); iter++)
{
uint32_t num = iter->first;
std::string name = iter->second;
printf("--0--num :%d, name:%s.\n",num,name.c_str());
}
//方法二:
for (std::map<uint32_t, std::string>::iterator iter = namelist.begin(); iter != namelist.end(); ++iter)
{
uint32_t num = iter->first;
std::string name = iter->second;
printf("--0--num :%d, name:%s.\n",num,name.c_str());
}
没有什么不同,我们看下执行结果
--0--num :1, name:1111.
--0--num :2, name:2222.
--0--num :3, name:3333.
--0--num :1, name:1111.
--0--num :2, name:2222.
--0--num :3, name:3333.
回答正确,两种方式都完美的遍历了所有的元素,那下面我们来看看每次每一轮迭代器的值吧
for (std::map<uint32_t, std::string>::iterator iter = namelist.begin(); iter != namelist.end(); )//iter++
{
uint32_t num = iter->first;
std::string name = iter->second;
printf("--0--num :%d, name:%s.\n",num,name.c_str());
printf("--0--num :%d.\n",(iter++)->first);
}
printf("\n-----------------------------------\n");
for (std::map<uint32_t, std::string>::iterator iter = namelist.begin(); iter != namelist.end(); )//++iter
{
uint32_t num = iter->first;
std::string name = iter->second;
printf("--0--num :%d, name:%s.\n",num,name.c_str());
printf("--0--num :%d.\n",(++iter)->first);
}
再来看下运行结果:
--0--num :1, name:1111.
--0--num :1.
--0--num :2, name:2222.
--0--num :2.
--0--num :3, name:3333.
--0--num :3.
-----------------------------------
--0--num :1, name:1111.
--0--num :2.
--0--num :2, name:2222.
--0--num :3.
--0--num :3, name:3333.
--0--num :803247488.
大家看出来区别来吗?方法一是 后置递增,方法二是后置递增
,这个会带来什么影响呢?功能上是没有影响的,但是性能上会有些差别。
后者内部需要一个临时对象,因为他必须存放迭代器的原本位置并返回之
_Myiter& operator++() //前置++重载
{ // preincrement
++*(_Mybase *)this;
return (*this);
}
_Myiter operator++(int) //有int参数 后置++重载
{ // postincrement
_Myiter _Tmp = *this;
++*this;
return (_Tmp);
}
后置式递增特点,在很多类运算符重载中,都需要为后置++和--在函数中定义一个临时变量,用于保存被更改之前变量的值作为返回值,然后在函数体中队变量进行相应操作。
Object a,b;
b=a++; 直观上来看,在a++中进行赋值操作前不能把a值改变, a的值赋前已经改变,只是b接受的是a改变前的副本temp当作的返回值
而前置式为先做自增自减运算,所以只需要对本身进行操作然后返回。由于后置式多出了这一步,所以效率低。
我们简单写个代码来验证下
std::map<uint32_t, std::string> namelist;
for (int i = 0; i<1000000; i++)
{
namelist.insert(std::make_pair(i, std::to_string(i)));
}
uint32_t startTime = getTime();
printf("\n------------------%d-----------------\n", startTime);
for (std::map<uint32_t, std::string>::iterator iter = namelist.begin(); iter != namelist.end();iter++ )
{
uint32_t num = iter->first;
std::string name = iter->second;
}
uint32_t endTime = getTime();
printf("\n------------------%d(diff:%d)-----------------\n", endTime, endTime-startTime);
for (std::map<uint32_t, std::string>::iterator iter = namelist.begin(); iter != namelist.end(); ++iter)
{
uint32_t num = iter->first;
std::string name = iter->second;
}
uint32_t endTime1 = getTime();
printf("\n------------------%d(diff:%d)-----------------\n", endTime1, endTime1-endTime);
我们来看下结果, 明显看出但就简单的遍历来讲, 使用前置式递增preincrement的优点,它比后置式递增postincrement效率高。
:
------------------643006724-----------------
------------------643006976(diff:252)-----------------
------------------643007212(diff:236)-----------------
网友评论