Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / December 2004

Tip: Looking for answers? Try searching our database.

Why does reading from a std::map not considered const?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Peteroid - 29 Nov 2004 04:16 GMT
Why does reading a member of a std::map not considered const? For example:

class My_Class
{
  int Get_Map_Value( int index ) const   // ** error ** not considered
const!!!
  {
      return m_Map[index] ; // note that m_Map is not changed, only read
from
  }
  std::map<int,int> m_Map ;
} ;

This really reeks havoc when to try to use const for its intended purpose...

 [==Peteroid==]

PS - I'm using MS VC++.NET and creating a Managed C++ application, if that
matters...
Doug Harrison [MVP] - 29 Nov 2004 04:46 GMT
>Why does reading a member of a std::map not considered const? For example:
>
[quoted text clipped - 15 lines]
>PS - I'm using MS VC++.NET and creating a Managed C++ application, if that
>matters...

If the key isn't already present in the map, map::operator[] will create a
new (K,V) pair and store it in the map, returning the V part by reference.
(Use of this operator requires the mapped_type be default-constructible.)

You can avoid this behavior by using map::find, though your function as
specified above will either have to return a default value or throw an
exception if that function returns end().

Signature

Doug Harrison
Microsoft MVP - Visual C++

Peteroid - 29 Nov 2004 12:25 GMT
So, if I get you right, using operator[] on a std::map isn't const because
of the POSSIBILITY it might give be given a key not already in the map.
Thus, even if my code insures I won't ever ask for an entry for which a key
doesn't already exist, it can't be declared const since I might not write
good code in this regard.

I believe I now understand, but feel it should have been the case that
operator[] was designed to allow const and to just cause an error if a
request for an entry where no key existed was asked for, and force people to
check on existence using the count() method (which returns 0 if the entry
doesn't exist and 1 if it does). That is, treat it much like trying to
access an array element that is out of bounds...

Thanks Doug!

[==Peteroid==]

> >Why does reading a member of a std::map not considered const? For example:
> >
[quoted text clipped - 23 lines]
> specified above will either have to return a default value or throw an
> exception if that function returns end().
Bret Pehrson - 29 Nov 2004 16:09 GMT
> So, if I get you right, using operator[] on a std::map isn't const because
> of the POSSIBILITY it might give be given a key not already in the map.
[quoted text clipped - 8 lines]
> doesn't exist and 1 if it does). That is, treat it much like trying to
> access an array element that is out of bounds...

const is an abortion in C++.

In theory, it sounds like a good idea.  In practice, it just doesn't work.
Peteroid - 30 Nov 2004 04:55 GMT
> const is an abortion in C++.
> In theory, it sounds like a good idea.
> In practice, it just doesn't work.

At the risk of starting a 'religous war', const is one of those 'road
blocks' we throw into our own programming path to make sure we don't
accidentally fall off a cliff. Another such road block is 'private'. You
could always define everything in a class to be 'public'. In fact, any code
that works will still work if 'private' is replaced by 'protected' or
'public'. However, 'private' prevents outside forces from changing such
variables without going through the mechanisms provided by the class. This
encapsulates the class so that it will perform more like a self-contained
object than merely a convenient and organizational combinantion of code and
data.

In the case of 'const' this allows programmers to insure that a class method
does not actually change anything in the class. In effect, it makes sure
that those methods you intend to be 'read-only' in nature with respect to
the class, are indeed, living up to that promise. It therefore acts as a way
of programming with a particualr style or mindset (a paradigm if you will),
to help find problems in dis-functioning code (via visual elimination of
methods that couldn't possibly change class members), and as a guard dog to
prevent conception errors at compile time.

I tend to use 'const' whenever I can. But, like I occasional must demote
(promote? guess it depends on your pov) 'private' to 'protected' (like when
it is faster and/or makes more sense for a child to have direct access than
to have to go through a 'property' method of the parent), sometimes I find I
must remove the 'const', simply because I realize it only changes an
un-important part of the class (such as a temporary convenience variable),
or as this thread is about, I'm using a standard template library container
which looks like it should act const, but in fact is not.

And, as you can see, I'm more than happy to construct run-on sentences to
make my points...lol

 [==Peteroid==]
Bret Pehrson - 30 Nov 2004 16:28 GMT
> > const is an abortion in C++.
> > In theory, it sounds like a good idea.
[quoted text clipped - 3 lines]
> blocks' we throw into our own programming path to make sure we don't
> accidentally fall off a cliff...

Yes, I know what const is for, and where and when appropriate.

The problem, as I said, that in practice, it just doesn't work.  I'll
elaborate:  If working on any medium scale+ project where there are more than a
few programmers and you use either a packaged framework and/or external C++
libraries, you quickly run into const problems.

You and your crew may do a great job of using const in the appropriate cases,
but if you reference something else that doesn't, then you are at an impasse --
you must either use some disgusting cast to cast away const or modify your own
code to remove const, even though your code is correct.

_This_ is what I mean when I say in practice, it doesn't work.  Like Hendrik,
I've used const for more than 10 years, and in my own code projects or other
similar small projects, const is just fine.  However, in just about every other
large scale case, const in my/our code has led to problems, issues, and
eventual removal because one or more of our third party libraries chose to
implement a particular method that should have been const but wasn't.

My casual thoughts (i.e. I haven't thought through it in any detail) is that
class methods should be _const_by_default_ and specifically de-const'd
where/when appropriate.
Doug Harrison [MVP] - 30 Nov 2004 17:27 GMT
>My casual thoughts (i.e. I haven't thought through it in any detail) is that
>class methods should be _const_by_default_ and specifically de-const'd
>where/when appropriate.

That would take some getting used to, but it's consistent with the current
fad(?) of explicitly granting privileges.

I think I'd genuinely like it applied to function parameters, most of which
should be declared const, and most of which rarely are. I'm speaking of
course about top-level const, e.g.

// What user should see:
void f(int x);
void g(char* x);

// What implementations normally would benefit from:
void f(int const x) {...}
void g(char* const x) {...}

You can do this already, of course, but it's a pain, and most people skip
it, even though they may diligently declare local variables const.

While we're at it, let's disable copying of classes by default.

And fix the casual approach to overriding virtual functions, which is prone
to accident.

Anything else? :)

Signature

Doug Harrison
Microsoft MVP - Visual C++

Bret Pehrson - 30 Nov 2004 18:16 GMT
> >My casual thoughts (i.e. I haven't thought through it in any detail) is that
> >class methods should be _const_by_default_ and specifically de-const'd
[quoted text clipped - 24 lines]
>
> Anything else? :)

Except for the const stuff, looks a lot like C#...
Hendrik Schober - 01 Dec 2004 13:45 GMT
> [...]
>
[quoted text clipped - 7 lines]
>
> Anything else? :)

 Make one-arg ctors explicit by default.

 Schobi

Signature

SpamTrap@gmx.de is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett

Hendrik Schober - 01 Dec 2004 13:57 GMT
> [...]
> >
[quoted text clipped - 9 lines]
>
>   Make one-arg ctors explicit by default.

 Oh, and automagically insert 'break'
 statements before each 'case'. (Or
 however it's done -- I don't care.
 It's just that even after a dozen
 years of C/C++ I still forget this
 damn 'break' once in a while. OTOH,
 I rarely ever want to fall through
 to the next label.)

 Schobi

Signature

SpamTrap@gmx.de is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett

Peteroid - 03 Dec 2004 01:41 GMT
>>Oh, and automagically insert 'break'
>>statements before each 'case'. (Or
>>however it's done -- I don't care.
.>>It's just that even after a dozen
>>years of C/C++ I still forget this
>>damn 'break' once in a while. OTOH,
>>I rarely ever want to fall through
.>>to the next label.)

I agree! I often fall into that (rookie?) trap when using 'switch'. Maybe
there should be two compiler directives to make either 'with break' or
'without break' the default in 'case' blocks ('without break' is the way it
is hard-wired now), and the addition of an 'unbreak' ('continue'?) to
override the default of 'break'.

Or, two 'switch's: 'switch' is as it is now (for compatibility), while
'switch_with_break' is a new one.

 [==Peteroid==]

> > [...]
> > >
[quoted text clipped - 20 lines]
>
>   Schobi
Hendrik Schober - 01 Dec 2004 13:53 GMT
> [...]
>
[quoted text clipped - 9 lines]
> you must either use some disgusting cast to cast away const or modify your own
> code to remove const, even though your code is correct.

 If there are ugly corners that you can
 not fix, isolate them using casts or by
 passing temporaries as arguments etc.

> _This_ is what I mean when I say in practice, it doesn't work.  Like Hendrik,
> I've used const for more than 10 years, and in my own code projects or other
> similar small projects, const is just fine.  However, in just about every other
> large scale case, const in my/our code has led to problems, issues, and
> eventual removal because one or more of our third party libraries chose to
> implement a particular method that should have been const but wasn't.

 I don't think I ever have /removed/ a
 'const' that should be there due to
 some other code getting it wrong.
 However, I have spent whole days on
 some projects just because I wanted
 to /add/ 'const' to some function that
 should have had it already but failed
 and that resulted in many other cases
 where a 'const' was missing. IIRC,
 there wasn't a single case where this
 did not discover a bug in the code
 base. Those that shook their heads
 when I "wasted" hours on this often
 soon were busy fixing the bugs found
 this way.

> My casual thoughts (i.e. I haven't thought through it in any detail) is that
> class methods should be _const_by_default_ and specifically de-const'd
> where/when appropriate.

 Not bad an idea. But I think there
 are a few more important cases where
 the default behaviour should be
 changed to the opposit.

 Schobi

Signature

SpamTrap@gmx.de is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett

Hendrik Schober - 30 Nov 2004 08:29 GMT
> [...]
>
> const is an abortion in C++.
>
> In theory, it sounds like a good idea.  In practice, it just doesn't work.

 I have used to for ten years and it
 has proven to be very useful to me.

 Schobi

Signature

SpamTrap@gmx.de is never read
I'm Schobi at suespammers dot org

"The presence of those seeking the truth is infinitely
to be prefered to those thinking they've found it."
Terry Pratchett

Doug Harrison [MVP] - 29 Nov 2004 16:13 GMT
>So, if I get you right, using operator[] on a std::map isn't const because
>of the POSSIBILITY it might give be given a key not already in the map.
>Thus, even if my code insures I won't ever ask for an entry for which a key
>doesn't already exist, it can't be declared const since I might not write
>good code in this regard.

I wouldn't necessarily characterize this as a "good code" issue. To provide
the non-const operator[], std::map has to be able to deal with:

m[k] = t;

for some k not already in the map. It would be subtle for the non-const
operator[] to add items but for const operator[] to throw for items that
don't already exist in the map.

>I believe I now understand, but feel it should have been the case that
>operator[] was designed to allow const and to just cause an error if a
>request for an entry where no key existed was asked for, and force people to
>check on existence using the count() method (which returns 0 if the entry
>doesn't exist and 1 if it does). That is, treat it much like trying to
>access an array element that is out of bounds...

I guess they figured that operator[] shouldn't change in definedness
depending on const vs. non-const, though the standard library isn't entirely
consistent with that philosophy. In any case, you can write your own indexer
functions that throw for items not already in the map, at some loss of
notational convenience. (Think vector::at, but as a non-member "lookup(m,
k)" or something...)

(Speaking of gotchas, note also that an insert() that finds the key doesn't
update the item already in the map. That got me once...)

>Thanks Doug!

No problem.

Signature

Doug Harrison
Microsoft MVP - Visual C++


Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.