unordered_set insert returns const_iterator ?
Hi while i am using boost unordered_set , and insert a new key value pair, it returns the iterator as a const one. In fact when i looked at the code, the iterator is a typedef to implementation::const_iterator ... so there is no way to gen an mutable iterator from the set, including begin() and end() is it a standard behavior or i am missing something ? thanks abir
On 20/03/2008, Abir Basak <abirbasak@gmail.com> wrote:
Hi while i am using boost unordered_set , and insert a new key value pair, it returns the iterator as a const one. In fact when i looked at the code, the iterator is a typedef to implementation::const_iterator ... so there is no way to gen an mutable iterator from the set, including begin() and end() is it a standard behavior or i am missing something ?
It's standard behaviour. The keys in unordered containers are const, because if you change it, it could change the position that the element should be in. And since the elements in unordered_sets unordered_multisets are just the keys, they are const as well. The situation is the same with std::set. There has been some debate on this in the past. The typical solution is to use an unordered_map, where the key is constant but the mapped type is not. Boost.Bimap, Boost.Multindex and Boost.Intrusive might offer alternative ways of dealing with this, but I don't know them well enough to say. Daniel
Daniel James wrote:
On 20/03/2008, Abir Basak <abirbasak@gmail.com> wrote:
Hi while i am using boost unordered_set , and insert a new key value pair, it returns the iterator as a const one. In fact when i looked at the code, the iterator is a typedef to implementation::const_iterator ... so there is no way to gen an mutable iterator from the set, including begin() and end() is it a standard behavior or i am missing something ?
It's standard behaviour. The keys in unordered containers are const, because if you change it, it could change the position that the element should be in. And since the elements in unordered_sets unordered_multisets are just the keys, they are const as well. The situation is the same with std::set. There has been some debate on this in the past.
The typical solution is to use an unordered_map, where the key is constant but the mapped type is not.
Boost.Bimap, Boost.Multindex and Boost.Intrusive might offer alternative ways of dealing with this, but I don't know them well enough to say.
Daniel
Thanks for replying .... The argument is justified. So i thought to separate out the key and use unordered_multimap instead. But facing another problem while calling equal_range The sample program shows the problem, //typedef std::multimap<char,int> Mymap; typedef boost::unordered_multimap<char, int> Mymap; Mymap c1; c1.insert(Mymap::value_type('a', 1)); c1.insert(Mymap::value_type('a', 2)); c1.insert(Mymap::value_type('b', 3)); c1.insert(Mymap::value_type('c', 4)); Mymap::iterator it,end; boost::tie(it,end) = c1.equal_range('a'); for( ; it!=end; ++it){ std::cout<<(*it).second<<" "; } Here the multimap version runs correctly, but unordered_multimap fails to run in the call equal_range (compiler MSVC 7.1 .NET 2003, and standard library from MS) ... the boost svn checkout from HEAD today) Thanks The error message is too complex, e:\boost\boost\unordered\detail\hash_table_impl.hpp(301) : error C2039: 'hash_table_data_equivalent_keys<std::allocator<std::pair<char const ,int> > >' : is not a member of 'boost::unordered_detail::hash_table_data_equivalent_keys<Alloc>::iterator_base' with [ Alloc=boost::unordered_detail::hash_types_equivalent_keys<std::pair<const char,int>,char,boost::hash<char>,std::equal_to<char>,std::allocator<std::pair<const char,int>>>::value_allocator ] e:\boost\boost\unordered\detail\hash_table_impl.hpp(255) : see declaration of 'boost::unordered_detail::hash_table_data_equivalent_keys<Alloc>::iterator_base' with [ Alloc=boost::unordered_detail::hash_types_equivalent_keys<std::pair<const char,int>,char,boost::hash<char>,std::equal_to<char>,std::allocator<std::pair<const char,int>>>::value_allocator ] e:\boost\boost\unordered\detail\hash_table_impl.hpp(300) : while compiling class-template member function 'void boost::unordered_detail::hash_table_data_equivalent_keys<Alloc>::iterator_base::increment_group(void)' with [ Alloc=boost::unordered_detail::hash_types_equivalent_keys<std::pair<const char,int>,char,boost::hash<char>,std::equal_to<char>,std::allocator<std::pair<const char,int>>>::value_allocator ] e:\boost\boost\unordered\detail\hash_table_impl.hpp(1962) : see reference to class template instantiation 'boost::unordered_detail::hash_table_data_equivalent_keys<Alloc>::iterator_base' being compiled with [ Alloc=boost::unordered_detail::hash_types_equivalent_keys<std::pair<const char,int>,char,boost::hash<char>,std::equal_to<char>,std::allocator<std::pair<const char,int>>>::value_allocator ] e:\cvs_checkout\read-ink\cplusplus\ink_app\test\test_inklib.cpp(72) : see reference to class template instantiation 'boost::unordered_detail::hash_iterator_equivalent_keys<Alloc>' being compiled with [ Alloc=boost::unordered_detail::hash_types_equivalent_keys<std::pair<const char,int>,char,boost::hash<char>,std::equal_to<char>,std::allocator<std::pair<const char,int>>>::value_allocator ]
On 20/03/2008, abir basak <abirbasak@gmail.com> wrote:
Here the multimap version runs correctly, but unordered_multimap fails to run in the call equal_range (compiler MSVC 7.1 .NET 2003, and standard library from MS) ... the boost svn checkout from HEAD today) Thanks
I don't have access to that compiler. I tried running similar code in Visual C++ 6.5 and Visual C++ express 8, and they both worked. I can try adding something to the unit tests but that will take me a while to work through. At the end of this email is the code I tested with, can you try it on your compiler? If it works, I'm doing something different to you, do you have any idea what? thanks, Daniel #include <boost/unordered_map.hpp> #include <boost/tuple/tuple.hpp> #include <iostream> int main() { typedef boost::unordered_multimap<char, int> Mymap; Mymap c1; c1.insert(Mymap::value_type('a', 1)); c1.insert(Mymap::value_type('a', 2)); c1.insert(Mymap::value_type('b', 3)); c1.insert(Mymap::value_type('c', 4)); Mymap::iterator it,end; boost::tie(it,end) = c1.equal_range('a'); for( ; it!=end; ++it) { std::cout<<(*it).second<<" "; } }
participants (3)
-
abir basak
-
Abir Basak
-
Daniel James