Hello
Whats the right way to return reference to element in a map (in one line):
Thanks for help!Code:class someclass { public: element &get_element(std::string key) { return *(m_map.find(key)); } private: std::map<std::string, element> m_map; };
Hello
Whats the right way to return reference to element in a map (in one line):
Thanks for help!Code:class someclass { public: element &get_element(std::string key) { return *(m_map.find(key)); } private: std::map<std::string, element> m_map; };
That would be:
Of course, if key does not exist then it would be added to the map. If you do not want this behaviour, then another option is:Code:class someclass { public: element& get_element(const std::string& key) { return m_map[key]; } private: std::map<std::string, element> m_map; };
Yet another option is to stick to what you have now, but state that if someone attempts to use a key that does not exist, the behaviour is undefined.Code:class someclass { public: element& get_element(const std::string& key) { std::map<std::string, element>:iterator iter = m_map.find(key); if (iter == m_map.end()) { throw std::out_of_range("Invalid key: " + key); } return *iter; } private: std::map<std::string, element> m_map; };
Last edited by laserlight; 04-22-2008 at 04:15 AM. Reason: Fixed typo error pointed out by matsp.
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
And yet another variation is:Code:class someclass { public: element &get_element(std::string key) { assert(m_map.find(key) != m_map.end()); return m_map.find(key)->second; } private: std::map<std::string, element> m_map; };
Last edited by Daved; 04-22-2008 at 06:35 AM. Reason: fix bug
In laserlight's post there is an ill-placed return keyword that needs to be removed to compile correctly:
--Code:std::map<std::string, element>:iterator iter = return m_map.find(key);
Mats
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
That is why the assert is an option. Based on previous threads from the OP, it is entirely likely that an invalid key is a programmer error and can only happen due to programming error. It is one step better than the "undefined behavior" solution by itself. The fact that the assert is compiled out of release builds is a positive, because that situation should never occur and so there should be no need to waste time checking the iterator against end().
Why will this produce the following error:
Code:class someclass { public: element &get_element(std::string key) { assert(m_map.find(key) != m_map.end()); return *(m_map.find(key)); } private: std::map<std::string, element> m_map; };Thanks again!Code:error C2440: 'return' : cannot convert from 'std::pair<_Ty1,_Ty2>' to 'element &'
Oh yes, we overlooked the fact that a map iterator is a pair consisting of the key and the value. Since you only want the value, you should return m_map.find(key)->second (or in my example, iter->second).
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
l2u's had threads about this over the last couple weeks you can search for if you're curious about the back story. It doesn't really matter for the point at hand though, since we're just discussing potential solutions rather than specifically identifying the "correct" one.
I think the assert is a valid solution even if recovery is possible. Look at vector's operator[] and at() functions. Both present valid solutions to the problem. One uses undefined behavior (potentially with an assert or debug-only error of some kind). The other uses an exception. You use each in different circumstances depending on what you need.
Personally, I would normally prefer a defined solution despite potential performance costs because I'd rather have the code work in all cases than prematurely optimize. However, the implementation cost of catching the out_of_range error in an appropriate place may be significant, and so leaving the behavior undefined might be more appropriate for a situation that should never happen.
With:
I get error:Code:return *(m_map.find(key)->second);
Code:error C2440: 'return' : cannot convert from 'std::string' to 'element &'
hmm... but the original post gives m_map as:
Clearly, std::string is the key type, element is the mapped type.Code:std::map<std::string, element> m_map;
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)