2017-10-16 20 views
0

En général, les conteneurs STL ne peuvent pas contenir des types non-CopyAssignable tels que des références. Si je construis le conteneur d'une manière qu'aucune copie ne devrait avoir lieu, alors le code est valide. Il compile avec std=c++11 et c++14 avec une version de gcc-7.2, mais est ce qui suit valide ou je peux m'attendre à ce qu'il casse avec une mise à niveau de bibliothèque? Dois-je utiliser reference_wrapper dans ce cas?Est-il légal de construire une référence non tenue contenant des références?

#include <unordered_map> 

struct S {}; 

void use (S&) {} 

void test() { 
    S s1, s2; 
    const std::unordered_map<int, S&> m{{0, s1}, {1, s2}}; 
    use(m.at(0)); 
} 

Modifier-je vraiment besoin d'une référence à la norme. Fonctionne pour moi aussi ne suffit pas, si une mise à jour conforme à la norme de la bibliothèque du compilateur/standard peut casser le code. Donc, la réponse donnée pour "unordered_map with reference as value" ne me suffit pas.

+4

Copie possible de [carte non triée avec référence comme valeur] (https://stackoverflow.com/questions/24719044/unordered-map-with-reference-as-value) – davidhigh

+0

dans les conteneurs généraux nécessitent CopyAssignable non seulement pour la construction , mais aussi de nombreux algorithmes peuvent ne pas fonctionner comme prévu – user463035818

Répondre

1

Je pense avoir trouvé une réponse moi-même pour ce cas précis d'utilisation:

La norme C++11 à l'article 23.5.4.3 pour l'accès élément unordered_map omet spécifiquement la liste des exigences relatives à la mapped_type, qui est S&, alors qu'avec operator[] il doit être DefaultConstructible.

mapped_type& at(const key_type& k); 
const mapped_type& at(const key_type& k) const; 

retours: une référence à x.second, où x est l'élément (unique) dont la clé est équivalente à k.

Lève: Objet d'exception de type out_of_range si aucun élément de ce type n'est présent.

C++17 indique également indirectement quelque chose à cet effet dans 26.5.4.3 et 26.5.4.4.

Par conséquent, le code ci-dessus devrait fonctionner avec n'importe quelle implémentation standard.

Cependant, il est vrai - comme l'a souligné dans les commentaires - que le conteneur après muter la construction ou l'application de tout algorithme qui nécessite la construction ou l'affectation ne fonctionnera pas value_type ou mapped_type de conteneur.