C++关于函数返回值的问题

lwjpker 2014-02-18 10:29:31
#include <boost/shared_ptr.hpp>
#include <map>
#include <string>
#include <iostream>

using namespace std;

class Test
{
private:
map<string, shared_ptr<map<string, string>>> m_Map;

public:
void test()
{
shared_ptr<map<string, string>> mapPtr1 = shared_ptr<map<string, string>>(new map<string, string>);
mapPtr1->insert(make_pair("1", "a"));
shared_ptr<map<string, string>> mapPtr2 = shared_ptr<map<string, string>>(new map<string, string>);
mapPtr2->insert(make_pair("2", "b"));

m_Map.insert(make_pair("IM", mapPtr1));
m_Map.insert(make_pair("HTTP", mapPtr2));
}

map<string, shared_ptr<map<string, string>>> getMap()
{
return m_Map;
}
};

int main(int argc, char *argv[])
{
Test obj;
obj.test();

map<string, shared_ptr<map<string, string>>>::iterator iter = obj.getMap().find("IM");
cout << iter->first << endl;

return 0;
}


有个同学写了类似上面的一段测试代码,我在main函数里修改了一下。经测试,上述代码中的obj.getMap().find("IM")这句返回的迭代器,在执行cout << iter->first << endl;这句时,弹出的错误是map/set iterators not dereferenceable。但若将上述代码修改为:

map<string, shared_ptr<map<string, string>>> MAP = obj.getMap();
map<string, shared_ptr<map<string, string>>>::iterator iter = MAP.find("IM");
cout << iter->first << endl;

则可以正常执行,想请教一下这两种情况到底差在哪里??
...全文
306 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
漫步者、 2014-02-19
  • 打赏
  • 举报
回复
这个iterator指向的一个range of elements or elements in an array , so you get a return that is unused.
漫步者、 2014-02-19
  • 打赏
  • 举报
回复
An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators (with at least the increment (++) and dereference (*) operators). The most obvious form of iterator is a pointer: A pointer can point to elements in an array, and can iterate through them using the increment operator (++). But other kinds of iterators are possible. For example, each container type (such as a list) has a specific iterator type designed to iterate through its elements. Notice that while a pointer is a form of iterator, not all iterators have the same functionality of pointers; Depending on the properties supported by iterators, they are classified into five different categories:
漫步者、 2014-02-19
  • 打赏
  • 举报
回复
引用 5 楼 lwjpker 的回复:
[quote=引用 3 楼 ADF1230 的回复:] 你单步调试一下,看看执行到cout << iter->first << endl;前map和iter的状态。
我试过了,在执行map<string, shared_ptr<map<string, string>>>::iterator iter = obj.getMap().find("IM");这句之后,iter就已经是一个无效的迭代期了,但是在执行期间我跟踪查看了在上述语句未执行完时,iter是有效的值。所以才有上述的猜想。[/quote] 不小心删掉了你的上一条回复,我给你找到了答案:
Iterator definitions
An iterator is any object that, pointing to some element in a range of elements (such as an array or a container), has the ability to iterate through the elements of that range using a set of operators (with at least the increment (++) and dereference (*) operators).

The most obvious form of iterator is a pointer: A pointer can point to elements in an array, and can iterate through them using the increment operator (++). But other kinds of iterators are possible. For example, each container type (such as a list) has a specific iterator type designed to iterate through its elements.

Notice that while a pointer is a form of iterator, not all iterators have the same functionality of pointers; Depending on the properties supported by iterators, they are classified into five different categories:
msdn上的。
Johnblx 2014-02-19
  • 打赏
  • 举报
回复
引用 2 楼 lwjpker 的回复:
试着猜想了一下,因为Test类的getMap()方法,返回值类型是对应的map值而不是引用,在返回时会构造一个副本返回。执行正确的时候因为定义了一个变量MAP将其保存。而不正确的时候,因为副本在执行完上述的obj.getMap().find("IM")语句后,就销毁了,所以相应的其对应的迭代器也对应失效。而(obj.getMap().find("IM"))->first该语句之所以正确,是因为返回的副本仍在生命期内,所以正确。不知道理解的是否有些道理,还望大神指教~~~
学习了,以前也有过类似的问题,但都是将语句分开写了。 没有研究过为什么。学习了
lwjpker 2014-02-19
  • 打赏
  • 举报
回复
引用 13 楼 wahaha_1986 的回复:
[quote=引用 2 楼 lwjpker 的回复:] 试着猜想了一下,因为Test类的getMap()方法,返回值类型是对应的map值而不是引用,在返回时会构造一个副本返回。执行正确的时候因为定义了一个变量MAP将其保存。而不正确的时候,因为副本在执行完上述的obj.getMap().find("IM")语句后,就销毁了,所以相应的其对应的迭代器也对应失效。而(obj.getMap().find("IM"))->first该语句之所以正确,是因为返回的副本仍在生命期内,所以正确。不知道理解的是否有些道理,还望大神指教~~~
应该是这样的,迭代器指向的临时对象已经被析构了。C++标准中写到“临时性对象的被摧毁,应该是对完整表达式(full-expression)求值过程中的最后一个步骤,该完整表达式造成临时对象的产生。”[/quote] 嗯,可能是我描述的不太好,我其实也是这样猜测的。谢谢你的回答~
lwjpker 2014-02-19
  • 打赏
  • 举报
回复
引用 12 楼 lyyslsw 的回复:
[quote=引用 2 楼 lwjpker 的回复:] 试着猜想了一下,因为Test类的getMap()方法,返回值类型是对应的map值而不是引用,在返回时会构造一个副本返回。执行正确的时候因为定义了一个变量MAP将其保存。而不正确的时候,因为副本在执行完上述的obj.getMap().find("IM")语句后,就销毁了,所以相应的其对应的迭代器也对应失效。而(obj.getMap().find("IM"))->first该语句之所以正确,是因为返回的副本仍在生命期内,所以正确。不知道理解的是否有些道理,还望大神指教~~~
学习了,以前也有过类似的问题,但都是将语句分开写了。 没有研究过为什么。学习了[/quote] 这个是同学问我的,我才发现这个问题。我自己基本上不这样写的,所以从来没遇到这个问题。发现了正好大家一起了解一下。
lwjpker 2014-02-19
  • 打赏
  • 举报
回复
引用 8 楼 vrace 的回复:
iter 指向了一个无效的 map! 试试
map<string, shared_ptr<map<string, string>>>& getMap()
{
    return m_Map;
}
返回引用
返回引用是没问题的,这个我知道。我只是想就着这个返回值为什么会有那样的错误,产生了疑问。谢谢你的回答。
wahaha_1986 2014-02-19
  • 打赏
  • 举报
回复
引用 2 楼 lwjpker 的回复:
试着猜想了一下,因为Test类的getMap()方法,返回值类型是对应的map值而不是引用,在返回时会构造一个副本返回。执行正确的时候因为定义了一个变量MAP将其保存。而不正确的时候,因为副本在执行完上述的obj.getMap().find("IM")语句后,就销毁了,所以相应的其对应的迭代器也对应失效。而(obj.getMap().find("IM"))->first该语句之所以正确,是因为返回的副本仍在生命期内,所以正确。不知道理解的是否有些道理,还望大神指教~~~
应该是这样的,迭代器指向的临时对象已经被析构了。C++标准中写到“临时性对象的被摧毁,应该是对完整表达式(full-expression)求值过程中的最后一个步骤,该完整表达式造成临时对象的产生。”
vrace 2014-02-18
  • 打赏
  • 举报
回复
iter 指向了一个无效的 map! 试试
map<string, shared_ptr<map<string, string>>>& getMap()
{
    return m_Map;
}
返回引用
lwjpker 2014-02-18
  • 打赏
  • 举报
回复
引用 3 楼 ADF1230 的回复:
你单步调试一下,看看执行到cout << iter->first << endl;前map和iter的状态。
我试过了,在执行map<string, shared_ptr<map<string, string>>>::iterator iter = obj.getMap().find("IM");这句之后,iter就已经是一个无效的迭代期了,但是在执行期间我跟踪查看了在上述语句未执行完时,iter是有效的值。所以才有上述的猜想。
漫步者、 2014-02-18
  • 打赏
  • 举报
回复
断点跟踪进去看一下就晓得了,不要去猜测错误
神-气 2014-02-18
  • 打赏
  • 举报
回复
你单步调试一下,看看执行到cout << iter->first << endl;前map和iter的状态。
lwjpker 2014-02-18
  • 打赏
  • 举报
回复
试着猜想了一下,因为Test类的getMap()方法,返回值类型是对应的map值而不是引用,在返回时会构造一个副本返回。执行正确的时候因为定义了一个变量MAP将其保存。而不正确的时候,因为副本在执行完上述的obj.getMap().find("IM")语句后,就销毁了,所以相应的其对应的迭代器也对应失效。而(obj.getMap().find("IM"))->first该语句之所以正确,是因为返回的副本仍在生命期内,所以正确。不知道理解的是否有些道理,还望大神指教~~~
lwjpker 2014-02-18
  • 打赏
  • 举报
回复

cout << (obj.getMap().find("IM"))->first << endl;
直接这样也是可以输出的,和上面又差在什么地方呢,希望谁能给解答一下,谢谢。

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧