Value type of map need not be default copyable

Marc Glisse marc.glisse@inria.fr
Wed Aug 8 13:48:00 GMT 2012


On Wed, 8 Aug 2012, François Dumont wrote:

> On 08/08/2012 09:34 AM, Marc Glisse wrote:
>> On Tue, 7 Aug 2012, Richard Smith wrote:
>> 
>>>> I've attached a patch for unordered_map which solves the rvalue
>>>> reference problem.  For efficiency, I've created a new
>>>> _M_emplace_bucket method rather than call emplace directly.
>>>> 
>>>> I've verified all libstdc++ tests pass (sorry for the previous
>>>> oversight) and am running the full GCC test suite now.  However, I'd
>>>> appreciate any feedback on whether this is a reasonable approach.  STL
>>>> hacking is way outside my comfort zone.  ;-)
>>>> 
>>>> If this looks good, I'll take a stab at std::map.
>>> 
>>> I think you should remove the mapped_type() argument from the call to
>>> _M_emplace_bucket. In C++11, the mapped_type is not required to be 
>>> copyable
>>> at all, just to be DefaultInsertable.
>> 
>> Indeed. The reason I was talking about emplace is that you want an object 
>> to be created only at the time the node is created. That might mean passing 
>> piecewise_construct_t and an empty tuple to emplace (otherwise it is too 
>> similar to insert). Or for unordered_map where the node functions are 
>> "exposed", you could just create the node directly without passing through 
>> emplace.
>> 
> This is what I try to do in the attached patch. I replace _M_insert_bucket 
> with _M_insert_node and use it for operator[] implementation. I have also 
> introduce a special std::pair constructor for container usage so that we do 
> not have to include the whole tuple stuff just for associative container 
> implementations.
>
> However one test is failing:
> /home/fdt/dev/gcc/libstdc++-v3/testsuite/23_containers/unordered_map/insert/array_syntax_move.cc:39:18: 
> required from here
> /home/fdt/dev/gcc-build/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/stl_pair.h:175:42: 
> error: use of deleted function '__gnu_test::rvalstruct::rvalstruct(const 
> __gnu_test::rvalstruct&)'
>  : first(std::forward<_T1>(__x)), second() { }
>
> I don't understand why it doesn't use the move constructor. I can't see any 
> std::forward call missing. Anyone ?

You are dealing with a pair<T1,T2> where T1 is const T3.

It is roughly the same issue as before, we end up trying to call a move 
constructor on a const&&.

You probably want your pair constructor to accept T3&&, not T1&&.

-- 
Marc Glisse



More information about the Libstdc++ mailing list