Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assignment operator requirement for Key type in std::map

Tags:

c++

c++11

clang++

It seems to suggest here What requirements must std::map key classes meet to be valid keys?, and in a few other posts, that the Key type of an srd::map must have an assignment operator. However I have not been able to find that requirement in the standard.

#include <map>

struct Foo
{
    Foo& operator=( const Foo& ) = delete;

    int id;
};

bool operator<( const Foo&, const Foo& ) { return( false ); }

int main( int, char** )
{
    std::map<Foo,int> a;
    std::map<Foo,int> b;

    a = b;   // Should this work if Foo does not have an assignment operator?

    return( false );
}

The above compiles with GCC 4.9 and Visual Studio 2013 but fails, complaining about the lack of an assignment operator, with clang 3.5 on an Ubuntu 14.10 box running the following command "clang++ -std=c++11 -stdlib=libc++ code.cpp". Clang does succeed when using the GCC standard library. I suspect the clang standard library is broken here.

like image 434
goneskiing Avatar asked Sep 30 '22 07:09

goneskiing


1 Answers

§23.1 [container.requirements.general]/p15 & Table 99:

In Table 99, X denotes an allocator-aware container class with a value_type of T using allocator of type A, u denotes a variable, a and b denote non-const lvalues of type X, t denotes an lvalue or a const rvalue of type X, rv denotes a non-const rvalue of type X, and m is a value of type A.

The relevant part of Table 99 (Allocator-aware container requirements) is:

+-----------+-------------+--------------------------------+------------+
|Expression | Return type |   Assertion/note               | Complexity |
|           |             | pre-/post-condition            |            |
|-----------+-------------+--------------------------------+------------+
|   a = t   |      X&     | Requires: T is CopyInsertable  | linear     |
|           |             | into X and CopyAssignable.     |            |
|           |             | post: a == t                   |            |
+-----------+-------------+--------------------------------+------------+

And then §23.2.4 [associative.reqmts]/p7 says

The associative containers meet all the requirements of Allocator-aware containers (23.2.1), except that for map and multimap, the requirements placed on value_type in Table 96 apply instead to key_type and mapped_type. [ Note: For example, in some cases key_type and mapped_type are required to be CopyAssignable even though the associated value_type, pair<const key_type, mapped_type>, is not CopyAssignable. —end note ]

Note that this references Table 96, but given the note the intent is clearly to cover Table 99 as well, since nothing in Table 96 actually requires CopyAssignable. Since the value_type, pair<const key_type, mapped_type>, is never CopyAssignable, reading the Table 99 requirements to refer to it would be rather absurd.

like image 75
T.C. Avatar answered Oct 07 '22 20:10

T.C.