[unordered_map] Trying to understand some errors
I'm using VS v9, just in case that matters in this case. I'm : using namespace std; using namespace boost; unordered_map< string, uint32_t > xrf1; unordered_map< string, uint32_t >::const_iterator& iter = xrf1.find( "hello" ); This is something I've used many times with the other containers (well, std::map at least), but here I'm getting a conversion error. This is resolved by either removing the reference marker, or removing the const qualifier. Can someone explain this please? I'd always thought that applying const was easily done, and if so, then a reference should be sufficient, right? Unless the const cast is marked as explicit somehow? And as a side(ish) question, is there any real need to worry about have an object versus reference to something like an iterator? I've always tried to use references where I can, but I wonder if I should "just say no" and use regular objects from now on? Thanks, -- Craig Longman If it's not *signed* by me, then please don't assume it *is* from me.
On May 3, 2011, at 1:04 AM, Craig Longman
unordered_map< string, uint32_t > xrf1; unordered_map< string, uint32_t >::const_iterator& iter = xrf1.find( "hello" );
This is something I've used many times with the other containers (well, std::map at least), but here I'm getting a conversion error. This is resolved by either removing the reference marker, or removing the const qualifier.
Can someone explain this please? I'd always thought that applying const was easily done, and if so, then a reference should be sufficient, right? Unless the const cast is marked as explicit somehow?
This code makes me shudder. Capturing the value returned from a function with a reference variable asserts that the function is itself returning a reference, not a value - and always will, for the life of the codebase. This is far more general than iterators. My rule of thumb is: return by value, store returned data by value. To answer your question, because xrf1 isn't const, its find() returns a non-const iterator. You're trying to capture a reference to a const_iterator, which isn't what you have in hand. But let's say you declared xrf1 as const unordered_map. That would probably compile - but the anonymous value returned by find() can be destroyed at the end of the statement, leaving you with a reference to a destroyed value and a ticket to Undefined Behavior.
On Mon, May 2, 2011 at 22:04, Craig Longman
I'm using VS v9, just in case that matters in this case.
unordered_map< string, uint32_t > xrf1; unordered_map< string, uint32_t >::const_iterator& iter = xrf1.find( "hello" );
This is something I've used many times with the other containers (well, std::map at least), but here I'm getting a conversion error.
VS is letting you do something not standards-compliant. You're trying
to bind a temporary to a reference-to-nonconst, which is illegal.
Try to do the same thing in a non-VS compiler with std::map and you'll
see it fail:
#include <map>
#include <string>
using namespace std;
int main() {
map< string, int > xrf1;
map< string, int >::const_iterator& iter = xrf1.find( "hello" );
}
In function 'int main()':
Line 7: error: invalid initialization of non-const reference of type
'__gnu_debug::_Safe_iterator , int> >, __gnu_debug_def::map ~ Scott
participants (3)
-
Craig Longman
-
Nat Goodspeed
-
Scott McMurray