Map Comparison Fails in Function Const
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10

Thread: Map Comparison Fails in Function Const

  1. #1
    Join Date
    Jan 2012
    Location
    United States
    Posts
    12

    Unhappy Map Comparison Fails in Function Const

    So I'm very confused on why I'm getting an error here. I've dumbed down my code for simplicity and removed irrelevant code. Hopefully it doesn't take away the issue.

    PHP Code:
    class Foo
    {
        public:
            
    bool IsNull() const;

        private:
            
    std::map<intint*> test;
    }

    bool Foo::IsNull() const
    {
        if (
    test[0] == 0)
            return 
    true;
        else
            return 
    false;

    I'm getting a "passing...discards qualifiers" error on my if statement and not sure why because I'm not changing anything. I know removing const or making test mutable fixes the issue. I've been taught to always make a function const if it doesn't change anything, in which case, have I finally come across an acceptable time to use mutable?

  2. #2
    Join Date
    Apr 1999
    Posts
    27,433

    Re: Map Comparison Fails in Function Const

    Quote Originally Posted by JaySoyer View Post
    So I'm very confused on why I'm getting an error here.
    I've been taught to always make a function const if it doesn't change anything
    And your const function does change things.

    The std::map operator [] is a non-const function. If that item 0 doesn't exist, operator [] creates a new key.
    Code:
    bool Foo::IsNull() const
    {
        if (test[0] == 0)
    Use const_iterator and map::find to query whether an item in the map is a certain value, not operator [] .
    Code:
    map<int, int*>::const_iterator it = test.find(0);
    if ( it != test.end() && it->second == 0)
    Also out of curiousity, what is the reason for int* as a data item in the map?

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; January 27th, 2012 at 01:51 PM.

  3. #3
    Join Date
    Jan 2009
    Posts
    596

    Re: Map Comparison Fails in Function Const

    The problem is that with std::map, the [] operator will insert the key if it is not already in the map. I.e., the [] operator cannot be called on a const map.

    Look here for more info: http://www.cplusplus.com/reference/stl/map/operator%5B%5D/

    In your case, you should be using map::find(x) instead, which returns an iterator to the element which has key 'x', or map::end if there is no such element.

    Edit:Doh! Paul beat me to the 'submit' button
    Last edited by Peter_B; January 27th, 2012 at 01:52 PM.

  4. #4
    Join Date
    Jan 2012
    Location
    United States
    Posts
    12

    Smile Re: Map Comparison Fails in Function Const

    The std::map operator [] is a non-const function. If that item 0 doesn't exist, operator [] creates a new key.
    The problem is that with std::map, the [] operator will insert the key if it is not already in the map. I.e., the [] operator cannot be called on a const map.
    Well that's a sneaky little devil. I'm so used to checking for null pointers that way, I neglected to see that there was a find method for maps.

    Also out of curiousity, what is the reason for int* as a data item in the map?
    Oh I changed that data type for readability. The original is:
    PHP Code:
    std::map<std::stringFileSystemNode<T>*> mSubFolders
    Using maps to create a simple file/directory structure.

    Thanx for the help

  5. #5
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,891

    Re: Map Comparison Fails in Function Const

    You should consider whether or not smart pointers are appropriate. They're usually safer than raw pointers.

  6. #6
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,315

    Re: Map Comparison Fails in Function Const

    Quote Originally Posted by JaySoyer View Post
    Well that's a sneaky little devil. I'm so used to checking for null pointers that way, I neglected to see that there was a find method for maps.
    It's even more dangerous than just "it's non const". If that data does not exist, it is default constructed, which means initialization with a non-NULL pointer. In turn, testing said pointer against 0 becomes irrelevant (!)

    Thank goodness you declared your IsNull as const, as the compiler saved you from shooting your own foot, and potentially hours worth of debugging. What a nightmare!

    ----
    I'm personally not a huge fan of map's interface. It is convenient, sure, because of the subscript syntax, but does not correctly model the map's inner working.

    I wrote myself little "get" and "set" functions for interface, inspired from boost's property map library. Not only is it more efficient, it also leaves little room for surprises. That and Meyers even says you should do it!
    Is your question related to IO?
    Read this C++ FAQ LITE article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  7. #7
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,891

    Re: Map Comparison Fails in Function Const

    I was under the impression that nonexistent values were zero-initialized. I have relied on this a few times for counting keys.

  8. #8
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,315

    Re: Map Comparison Fails in Function Const

    Quote Originally Posted by Lindley
    I was under the impression that nonexistent values were zero-initialized.
    Yeah, or more generally, value-initialised.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  9. #9
    Join Date
    Jan 2012
    Location
    United States
    Posts
    12

    Re: Map Comparison Fails in Function Const

    Quote Originally Posted by monarch_dodra View Post
    I'm personally not a huge fan of map's interface. It is convenient, sure, because of the subscript syntax, but does not correctly model the map's inner working.

    I wrote myself little "get" and "set" functions for interface, inspired from boost's property map library. Not only is it more efficient, it also leaves little room for surprises. That and Meyers even says you should do it!
    So you mean the subscripting takes away from the fact its a Red Black tree? I didn't think you could get more efficient then O(Log N) access with that type of tree.

    I always here so many references for using Boost. One of these days I'll get around to it.

  10. #10
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,891

    Re: Map Comparison Fails in Function Const

    Quote Originally Posted by JaySoyer View Post
    So you mean the subscripting takes away from the fact its a Red Black tree? I didn't think you could get more efficient then O(Log N) access with that type of tree.
    Asymtotically, operator[] has the same efficiency as using lower_bound followed by insert if necessary. But using lower_bound followed by insert is faster by a constant factor.

    Note: I suggested using lower_bound rather than find. If you are just querying whether a given item exists, then find is okay; but if you wish to insert the item if it does *not* exist, then lower_bound is slightly better because the iterator returned from it (even if it doesn't point to the item you want) can be used as a hint to insert() to speed up that function.

    The reason why this is faster than operator[] is because in the expression m[i] = A where i does not exist in map m, a key will first be default-constructed and then copied over; by contrast, with lower_bound followed by insert, only a copy construction is necessary. The difference is minor but nonzero.

    I always here so many references for using Boost. One of these days I'll get around to it.
    Boost is a collection of useful things. Some parts of it are more intimidating than others. You should take a look to see what's available, but don't feel compelled to start using everything in there immediately.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center