views:

169

answers:

3

Please consider the following code:

#include "boost/ptr_container/ptr_map.hpp"

int main()
{
        typedef boost::ptr_multimap<char, const int> M;
        M m;
        char c = 'c';
        int* j = new int(7);
        m.insert(c, j);
        return 0;
}

The gcc 4.3.3 compiler fails to compiler the above code. Am I doing something wrong by inserting a non-const? Can't I store a pointer to const in the multimap?

try.cpp: In function ‘int main()’:
try.cpp:8: error: expected primary-expression before ‘=’ token
/usr/include/c++/4.3/bits/stl_pair.h: In constructor ‘std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U1 = char, _U2 = const int*, _T1 = const char, _T2 = void*]’:
boost/boost_1_39_0/boost/ptr_container/ptr_map_adapter.hpp:765:   instantiated from ‘typename boost::ptr_container_detail::ptr_map_adapter_base<T, VoidPtrMap, CloneAllocator, Ordered>::iterator boost::ptr_multimap_adapter<T, VoidPtrMultiMap, CloneAllocator, Ordered>::insert_impl(const typename boost::ptr_container_detail::ptr_map_adapter_base<T, VoidPtrMap, CloneAllocator, Ordered>::key_type&, typename boost::ptr_container_detail::ptr_map_adapter_base<T, VoidPtrMap, CloneAllocator, Ordered>::mapped_type) [with T = const int, VoidPtrMultiMap = std::multimap<char, void*, std::less<char>, std::allocator<std::pair<const char, void*> > >, CloneAllocator = boost::heap_clone_allocator, bool Ordered = true]’
boost/boost_1_39_0/boost/ptr_container/ptr_map_adapter.hpp:799:   instantiated from ‘typename boost::ptr_container_detail::ptr_map_adapter_base<T, VoidPtrMap, CloneAllocator, Ordered>::iterator boost::ptr_multimap_adapter<T, VoidPtrMultiMap, CloneAllocator, Ordered>::insert(typename boost::ptr_container_detail::ptr_map_adapter_base<T, VoidPtrMap, CloneAllocator, Ordered>::key_type&, typename boost::ptr_container_detail::ptr_map_adapter_base<T, VoidPtrMap, CloneAllocator, Ordered>::mapped_type) [with T = const int, VoidPtrMultiMap = std::multimap<char, void*, std::less<char>, std::allocator<std::pair<const char, void*> > >, CloneAllocator = boost::heap_clone_allocator, bool Ordered = true]’
try.cpp:9:   instantiated from here
/usr/include/c++/4.3/bits/stl_pair.h:106: error: invalid conversion from ‘const void*’ to ‘void*’

I also tried but failed with const casting j before insertion.

A: 

I haven't used boost but the problem seems to me that your defined map is expecting a const int and you are passing an int pointer to it. Try inserting the value in map by de-referencing variable 'j'.

Edit: Ahh... just checked. This is a ptr map and should be expecting a pointer and not an int as I said earlier. The problem in that case might be of const vs non-const value.

Aamir
+2  A: 

That seems to be the problem. It compiles fine without the const in the template parameters.

rlbond
does that mean this might be a bug in the library?
Amit Kumar
+1  A: 

From what i can tell, it seems to be a bug in the boost library.

But i don't understand why you would want your int* to be const. You're delegating the management of the memory for this item to the ptr container. It's only fair to provide it with non-const items. If you don't want users of this container to retrieve the pointer and modify it, i suggest you insert a class layer to only return const elements.

Benoît
Memory management can be done on pointer to a const too, as a pointer to a const can be deleted.
Amit Kumar
Right. But you must admit it's a weird language feature.
Benoît