C++11 initialiser la carte
Je suis en train d'initialiser un STL carte à l'aide de C++11 de la syntaxe, mais qui ne semble pas fonctionner. Après l'initialisation, lorsque j'essaie d'accéder à l'élément, il tente d'appeler le constructeur privé de Foo. Ai-je raté quelque chose? Il fonctionne si j'utilise. Je me demandais si je pouvais utiliser l'opérateur[] pour accéder à la initialisé valeurs...
#include <map>
#include <string>
class Foo{
public:
int a, b;
Foo(int a_, int b_){
a = a_;
b = b_;
}
private:
Foo(){};
};
int main(){
std::map<std::string, Foo> myMap = { {"1", Foo(10,5)}, {"2", Foo(5,10)} };
int b = myMap["1"].b; //it tries to call private constructor of Foo.
return 0;
}
OriginalL'auteur Negative Zero | 2012-06-07
Vous devez vous connecter pour publier un commentaire.
Lorsque vous utilisez le
operator[]
sur une carte, vous pouvez utiliser l'opérateur d'obtenir soit une valeur de la carte ou affecter une valeur dans la carte. Pour affecter la valeur de la carte, la carte doit construire un objet du type de la valeur, et le retourner par référence, de sorte que vous pouvez utiliseroperator=
pour remplacer un objet existant.Par conséquent, le type doit être par défaut constructible de sorte qu'un nouvel objet peut être créé pour vous affecter.
Au moment de l'exécution, le constructeur ne sera pas appelé si la clé existe déjà, mais le compilateur n'a aucun moyen de savoir si vous aurez jamais utiliser
operator[]
pour accéder à une valeur qui n'existe pas, donc il faut le constructeur à être public.OriginalL'auteur Ken Bloom
operator[]
de la carte nécessite le type de défaut constructible, parce qu'il crée une nouvelle entrée si l'un n'existe pas.Vous pouvez utiliser
at()
au lieu de cela, ce qui déclenche si l'entrée n'existe pas:mais dead code à compiler.
C++11 exige en effet la
DefaultConstructible
concept pourmap<>::operator[]
(§23.4.4.3/2,6).Vrai que... je n'étais pas à penser clairement et lire que le constructeur était en fait .
Ne pourriez-vous pas, en théorie, un const
operator[]
et SFINAE la non-const version dans le cas où il n'y a pas de constructeur par défaut? Ce serait probablement complètement déroutant, mais; le nouveauat()
est clairement une meilleure solution.OriginalL'auteur R. Martinho Fernandes