I would like to use maps as a container type, but I don't like how the
[] operator returns a default value. Is there a way to make [] return
NULL if it can't find the value?
I know I can do this:
typedef numMap map<int,myClass*>;
numMap nums;
if( nums.find(99) != nums.end() )
{
cout << "nums[99] is: " << nums[99] << endl;
}
I don't know how efficient this is, as it looks up the key 99 twice. To
avoid this situation:
numMap::iterator itr = nums.find(99);
if( itr != nums.end() )
{
cout << "nums[99] is: " << *nums << endl;
}
I don't find all this very convenient. Perhaps I am just complaining
too much.
~S 6 2909
"shea martin" <sa******@telus.net> wrote... I would like to use maps as a container type, but I don't like how the [] operator returns a default value. Is there a way to make [] return NULL if it can't find the value?
Don't use operator[].
I know I can do this:
typedef numMap map<int,myClass*>; numMap nums;
if( nums.find(99) != nums.end() ) { cout << "nums[99] is: " << nums[99] << endl; }
I don't know how efficient this is, as it looks up the key 99 twice. To avoid this situation:
numMap::iterator itr = nums.find(99); if( itr != nums.end() ) { cout << "nums[99] is: " << *nums << endl; }
I don't find all this very convenient. Perhaps I am just complaining too much.
Yep.
Victor
shea martin <sa******@telus.net> wrote in message news:<3F**************@telus.net>... I would like to use maps as a container type, but I don't like how the [] operator returns a default value. Is there a way to make [] return NULL if it can't find the value?
First, the default value for a pointer is NULL, so it *does* return
NULL if it can't find the value. However, you might be concerned that
operator[] inserts the element if it wasn't already present, and also
that, because of this, it can't be used on const maps.
I know I can do this:
typedef numMap map<int,myClass*>; numMap nums;
if( nums.find(99) != nums.end() ) { cout << "nums[99] is: " << nums[99] << endl; }
I don't know how efficient this is, as it looks up the key 99 twice.
Yes, it is, isn't it...
To avoid this situation:
numMap::iterator itr = nums.find(99); if( itr != nums.end() ) { cout << "nums[99] is: " << *nums << endl; }
That's how it is intended to be used.
I don't find all this very convenient. Perhaps I am just complaining too much.
Sounds like it. However, don't forget that C++ actually allows you to
write your own functions:
template <typename K, typename V, typename P, typename A>
V *find (std::map<K, V *, P, A> &m, const K &key) {
typename std::map<K, V *, P, A>::iterator i = m.find(key);
return (i != m.end()) ? i->second : 0;
}
template <typename K, typename V, typename P, typename A>
const V *find (const std::map<K, V *, P, A> &m, const K &key) {
typename std::map<K, V *, P, A>::const_iterator i = m.find(key);
return (i != m.end()) ? i->second : 0;
}
class myClass;
int main () {
typedef std::map<int, myClass *> numMap;
numMap nums;
if (myClass *obj = find(nums, 99)) {
std::cout << "nums[99] is: " << obj << std::endl;
}
}
- Shane
shea martin <sa******@telus.net> wrote in message news:<3F**************@telus.net>... I would like to use maps as a container type, but I don't like how the [] operator returns a default value. Is there a way to make [] return NULL if it can't find the value?
Blah, it's annoying behavior in certain situations I'll agree, but
there's no good way for it to be implemented as you (and I) desire.
Returning null works if the map value is a pointer (and in fact this
is what happens, though it still adds a null pointer to the map which
is probably not what you want), but not otherwise. There are three
alternatives:
1. Raise an exception,
2. Use something like the boost::optional,
3. Act like set and return a pair with the second value a bool to
indicate if it was in the map.
The first option would rarely be ideal, as exceptions are somewhat
costly at runtime and such an error would usually not be of a nature
that would merit their use.
The second and third options are very close to the same solution, but
both destroy the niceness of the [] syntax.
Besides, doing so would then make it impossible to insert values into
the map using [], so you can only have it one way.
I know I can do this:
typedef numMap map<int,myClass*>; numMap nums;
if( nums.find(99) != nums.end() ) { cout << "nums[99] is: " << nums[99] << endl; }
I don't know how efficient this is, as it looks up the key 99 twice. To avoid this situation:
numMap::iterator itr = nums.find(99); if( itr != nums.end() ) { cout << "nums[99] is: " << *nums << endl; }
I don't find all this very convenient. Perhaps I am just complaining too much.
~S sb******@cs.uic.edu (Shane Beasley) wrote in message news:<2f**************************@posting.google. com>... shea martin <sa******@telus.net> wrote in message news:<3F**************@telus.net>...
template <typename K, typename V, typename P, typename A> V *find (std::map<K, V *, P, A> &m, const K &key) { typename std::map<K, V *, P, A>::iterator i = m.find(key); return (i != m.end()) ? i->second : 0; }
This is non-portable, as std::map may have extra
implementation-defined arguments. You'd need something like
template < typename MAP, typename pV = typename MAP::value_type >
pV find ( MAP &m, typename MAP::key_type const& key )
( nested types could be wrong, but you get the idea )
Regards,
--
Michiel Salters
<snip> In "The C++ Programming Language" Third edition on page 374 he says: "Exception handling is a less structured mechanism than local control structures such as if and for and is *often les efficient* when an exception is actually thrown." Looks like it is costly at run time, though I guess the cost is implementation specific.
He is saying that a thrown exception may be somewhat less efficient than an
if/then/else! If it's even in the ballpark, that's still pretty efficient.
However, to select a design for a relatively rare event like not finding
something you expect to find in a map, run time efficiency would be WAY down
my list of criteria. Maintainability would probably be first, as it usually
is.
Exceptions are a great feature of the C++ language, and refusing to use them
based on antecdotal evidence of run time inefficiency is unsound IMHO. -- "Codito ergo sum" Roel Schroeven
--
Cycho{HHR} http://home.rochester.rr.com/cyhome/
"Evan" <ee****@psu.edu> wrote in message
news:3f**************************@posting.google.c om... "Cy Edmunds" <ce******@spamless.rochester.rr.com> wrote in message
news:<I_*******************@twister.nyroc.rr.com>. .. Costly at run time? What makes you think so? Stroustrop says they are so efficient at runtime that it is tempting to just use them as control structures. (But then he says not to anyway.)
Hmmmm, I've recently read somewhere that they are somewhat inefficient. I can't remember where (in fact, the delay in responding is partially to see if I would think of it) or I'd give you a reference. It's possible that it was wrong as I too have heard of exceptions used for control structures.
Still, that wasn't the main reason I decided that they were inappropriate. The main reason was that which I wrote later:
Besides, doing so would then make it impossible to insert values into the map using [], so you can only have it one way.
I thought that it might be possible to optionally install and uninstall exception handlers for [], but dismissed it. However, I have since read in Josuttis about the standard streams using a similar approach to dealing with input errors, so maybe that could be an optional extension for library makers (I'm not sure if it conflicts with any of the standard, though I suspect it might with an exception gurantee).
-Evan
OK, you have shamed me into getting around to publish some code which in
fact lets you do it "both ways". You can go with [] if that suits you but
use some functions which throw exceptions otherwise. Just look under
"throwmap" in the link in my sig.
--
Cy http://home.rochester.rr.com/cyhome/ This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Fred Ma |
last post by:
Hello,
I was looking at Meyers's "Effective STL", item 23
about choosing between vectors and maps (at least
that the choice for me). In many cases, using
sorted vectors is faster for lookups. ...
|
by: maltchev |
last post by:
i need to insert data from an xml file into sql server table.
the xml file contains only one record.
how to insert the data? how to map the names of the fields in the xml file
and the table?...
|
by: Sean |
last post by:
Have you ever wanted to add the great features inherent in Google Maps?
Here is how you do it.
==============
== STEP ONE ==
==============
Create a new MS Access form called frmGoogleMap....
|
by: roberts.noah |
last post by:
It is my understanding that if you contain vectors or maps you don't
need to create copy constructors because the default calls that
constructor. It is my understanding that if you use these types...
|
by: Anamika |
last post by:
I want to create a map,which will be having string as a key and the
related data as a structure...
So can I use user defined data types as the data in maps? If so How I
can use it...
What is...
|
by: Hicham Mouline |
last post by:
Hello,
I am attempting to design a class:
class C {
std::map<double, const Ama;
std::map<double, const Bma;
..
|
by: jlm699 |
last post by:
I've looked at the other articles about maps of maps and am still stuck on this!
I'm trying to basically make an enumeration of a data monitoring app. Instead of displaying numbers for certain...
|
by: brad |
last post by:
Do maps convert to multimaps if the same key is inserted more than once?
|
by: C++Liliput |
last post by:
I have a custom String class that contains an embedded char* member.
The copy constructor, assignment operator etc. are all correctly
defined. I need to create a map of my string (say a class...
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: ryjfgjl |
last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
| |