
Hello, new to this list... did not find anything similar on net. One of the annoyances with std::map is that if you work with const maps, then there is no "one line" code to get an element knowing the key. given the map const map<string, string> aStringMap; I cannot write const string &s = aStringMap["key"]; process(s); I should write: map<string, string>::const_iterator it=aStringMap.find("key") if( it != aStringMap.end() ) { process(it->second) } so would be nice to have a macro like BOOST_CONSTMAPFIND(aStringMap, "key", data) { processResult( data ); } the version if(BOOST_CONSTMAPFIND(l_map, l_key, l_data) ) { } Seems to be impossible to implement -- rgrds, mobi phil being mobile, but including technology http://mobiphil.com

Hi mobi phil,
If that is really what you want and you don't care about performances, I can propose you for example the following : [code] #include <boost/foreach.hpp> #include <stdexcept> struct ConstMapHelper { template <class T,class U> static const U& getConst(const T& pKey,const std::map<T,U>& pMap) { typedef std::pair<const T,U> TPair; BOOST_FOREACH(const TPair& lPair,pMap) { if(lPair.first==pKey) { return lPair.second; } } throw std::domain_error("[ConstMapHelper::getConst] key not found"); // do what you want } }; [/code] And then when you want to use it : // construction of the const map std::map<std::string, std::string> lMap; lMap.insert(std::make_pair("1","1")); lMap.insert(std::make_pair("2","2")); const std::map<std::string, std::string> lMapConst(lMap); // access const std::string key = "5"; // the key const std::string& s = ConstMapHelper::getConst(key,lMapConst); // will throw exception because "5" is not in the map. You can even make it a true one liner if you get rid of the reference in the 'key' parameter. Hope this helps, Best regards, Pierre Morcello --- En date de : Mar 20.10.09, mobi phil <mobi@mobiphil.com> a écrit :

Pierre Morcello wrote:
That is horribly inefficient: O(N). Try this instead (untested): template <class T, class U> U const & get_value(std::map<T,U> const & _map, T const & _key) { typename std::map<T,U>::const_iterator it(_map.find(_key)); if (it != _map.end()) { return it->second; } throw std::domain_error("key not found"); } That is O log(N).
And then when you want to use it :
std::string const & s(get_value(lMapConst, "5")); _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Thanks for the replies... However I forgot to put in my question that I am looking for a macro and not template if possible, and for a solution as elegant as BOOST_FOREACH, where you have to code as less as possible. It not (only :) ) that I am lazy to write, but I think the resulting code would be easier to read. furthermore: 1. exception... throwing the exception removes the complexity of writing but introduces the complexity of exception (writing code + runtime). 2. pointer... use cases I would like to avoid pointers, as I have other constraints to work with const references. I was thinking all the day about this little "handicap" of the std::map. One way would be to have the concept of invalid object of the map data type that could be returned to satisfy the constraint of the reference, and a "horrible" function like bool return; const data_type & data = map.find(key, bool) if( return ) { //use the data } With this approach is that the "return" variable has to be declared. with the form I proposed BOOST_CONSTMAPFIND(aStringMap, "key", data) { processResult( data ); } the problem is that I do not know how to detect the type of data knowing in the map object. I thought for the moment that BOOST_FOREACH would "automatically" declare the type in the container (using non-standard typeof for eg), but revisiting again BOOST_FOREACH documentation i see that it declares the type. vector<int> v; BOOST_FOREACH( int i, v) etc. so it seems that if I declare the type of the data, my job becomes easy, a sort of "problem solved" const map<string, Mytype> & mymap = getMap(); //I changed the order of variables BOOST_CONSTMAPFIND(const Mytype &data, "key", mymap) { processResult(data); } and pair for non-const BOOST_MAPFIND(Mytype &data, "key", mymap) probably with some trick (probably sthg. similar used in BOOST_FOREACH), one could merge theh two macros. I am now two tired, but will write tomorrow the macro, test it, and would be happy if boost would accept it into the macros family. -- rgrds, mobi phil being mobile, but including technology http://mobiphil.com

at the end that is also not bad... It is still not clear for me how well for eg. gcc can optimize code generation if I would have such macros for like 100 types arround. In the worst case I would have extra 100 functions + extra overhead of function call. On Wed, Oct 21, 2009 at 1:04 AM, Steven Watanabe <watanabesj@gmail.com> wrote:
-- rgrds, mobi phil being mobile, but including technology http://mobiphil.com

mobi phil wrote: Please don't top post and don't overquote.
Don't optimize until you know you need it. Macro code makes for harder debugging and can lead to code bloat. Whether the alternative is inlined or is a function call, and what effect those have on performance are subjects to investigate once a solution is available.
_____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

mobi phil wrote:
How does a macro reduce the code you write? Your example is: BOOST_CONSTMAPFIND(aStringMap, "key", data) { processResult( data ); } My version was: data_type & data(get_value(aStringMap, "key")); processResult(data); Looking at your example here, it seems that you want this logic: if (find "key" in aStringMap) { // initialize data to reference the value for "key" processResult(data); } I had thought you wanted to assume that the value was always found. Given what I now understand, your macro would need to be something like this (ignoring necessary encapsulation details and not implementing the std::map to type mappings): #define BOOST_CONSTMAPFIND(_map, _key, _value) \ const_iterator_type_from(_map) const it(_map.find(_key)); typedef data_type_from(_map) data_type; data_type dummy; data_type * value(&dummy); data_type & _value(*value); if (it != _map.end()) { value = &it->second; }
I had understood your initial use case to imply that you assumed the value was found. I didn't recognize that you meant the macro to be a conditional controlling the following block.
Not all types have an unused value to indicate invalidity.
That's the unimplemented part in my macro above.
You need the iterator type, too. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Steven Watanabe wrote:
The original use case was written assuming the element was found. To satisfy that, you need to return a reference and throw an exception. If the OP is happy with testing a pointer, I agree with you. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.
participants (4)
-
mobi phil
-
Pierre Morcello
-
Steven Watanabe
-
Stewart, Robert