2014-12-01 9 views
5

Sembra suggerire qui What requirements must std::map key classes meet to be valid keys? e, in alcuni altri post, che il tipo di chiave di una srd :: map deve avere un operatore di assegnazione. Tuttavia non sono stato in grado di trovare quel requisito nello standard.Requisito dell'operatore di assegnazione per il tipo di chiave in std :: map

#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); 
} 

È possibile che compila con GCC 4.9 e Visual Studio 2013, ma non riesce, lamentando la mancanza di un operatore di assegnazione, con clangore 3.5 su una casella di Ubuntu 14.10 con il seguente comando "clang ++ -std = C++ 11 -stdlib = libC++ code.cpp ". Clang riesce quando si utilizza la libreria standard GCC. Sospetto che la libreria standard clang sia interrotta qui.

+0

++ 1 Posso pensare a poche ragioni pratiche per essere necessario. Questo incarico dovrebbe essere fatto facilmente con il costrutto di copia, per esempio. Hmm. – Yakk

risposta

4

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

In Tabella 99, X indica una classe contenitore allocatore-consapevole con value_type di T usando allocatore di tipo A, u indicato un variabile, a e b denotano lvalue non const di tipo X, t denota un Ivalue o rvalue const di tipo X, rv indicata una valore non costante del tipo X e m è un valore di tipo A.

La parte rilevante della Tabella 99 (requisiti relativi al serbatoio Allocatore-aware) è:

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

E poi §23.2.4 [associative.reqmts]/p7 dice

L'associativa i contenitori soddisfano tutti i requisiti di Contenitori di identificazione dell'allocatore (23.2.1), ad eccezione di quelli per map e multimap, i requisiti immessi in value_type in T 96 in grado di applicare invece a key_type e mapped_type. [Nota : Ad esempio, in alcuni casi key_type e mapped_type sono tenuti a essere CopyAssignable anche se gli associati value_type, pair<const key_type, mapped_type>, non è CopyAssignable. - nota end]

Si noti che questo riferimenti Tabella 96, ma data la nota l'intento è chiaramente quello di coprire Tabella 99, nonché, dal momento che nulla nella Tabella 96 richiede in realtà CopyAssignable. Poiché lo value_type, pair<const key_type, mapped_type>, non è mai CopyAssignable, la lettura dei requisiti della Tabella 99 per fare riferimento ad essa sarebbe piuttosto assurda.

+0

Grazie per quello, ho perso il bit 23.2.4 facendo riferimento al contenitore non associativo. – goneskiing

+0

L'implicazione della "Nota:" in 23.2.4 è che la coppia non deve essere CopyAssignable. Se è così, questo è dove libC++ potrebbe essere sbagliato in quanto assegna semplicemente una coppia a un'altra coppia. Trovo che parole come "in alcuni casi" un po 'strane, sembrino consentire a diverse implementazioni di accettare codice diverso. Forse i concetti ci salveranno tutti! – goneskiing

+0

@goneskiing Non è possibile assegnare una 'coppia ' perché quell'elemento è' const', e il requisito di Table 99 di CopyAssignable è su 'value_type' a meno che non sia negato da 23.2.4/p7. –

Problemi correlati