2014-04-23 4 views
1

Je reçois une erreur étrange de Clang lors de la compilation de ce qui devrait être une simple ligne de code.Mauvais constructeur std :: vector

Ce code produit une erreur:

size_t s = 5; 
std::vector<double> bestScores{s, -1.0}; 

J'essaie simplement d'utiliser constructor #2 pour remplir un nouveau vecteur avec cinq valeurs -1,0. L'erreur que je reçois est L'expression non constante ne peut pas être réduite du type 'type_taille' (alias 'unsigned long') à 'double' dans la liste d'initialisation.

Que se passe-t-il? Cela compile bien:

std::vector<double> bestScores{5, -1.0}; 

Est-il en train d'essayer d'utiliser le constructeur de la liste d'initialisation? Je pensais que vous aviez besoin de deux accolades pour que:

std::vector<double> bestScores{{5, -1.0}}; 
+3

Vous n'avez pas besoin de deux accolades pour le constructeur de liste d'initialisation, à l'exception de 'std :: array' pour des raisons confuses et archaïques. –

+0

@MooingDuck Cela doit avoir été ce à quoi je pensais. Merci –

+2

Peut-être que vous devriez lire [C++ 11 - Uniform initialization] (http://en.wikipedia.org/wiki/C++11#Uniform_initialization), en particulier les deux derniers paragraphes. –

Répondre

8

Le problème est que vous construisez le vecteur en utilisant une liste d'initialisation fermée accolade. Cela favorise le constructeur std::initializer_list<T> le cas échéant. Dans ce cas, la liste size_t, -1.0 est compatible avec std::initializer_list<double>, de sorte que le constructeur soit sélectionné. Vous devez utiliser l'ancien style, C 03 de construction:

std::vector<double> bestScores(s, -1.0); 

C'est l'un des gotchas de initializers joint brace. Ils ne fonctionnent pas bien pour certaines instanciations de conteneur de bibliothèque standard. Vous devez vous rappeler que le constructeur std::initializer_list l'emportera sur les autres.

4

Le problème est que lorsqu'une classe a un constructeur std::initializer_list, elle préférera que lors de l'utilisation de la syntaxe d'initialisation uniforme si les arguments sont convertibles en le type de la liste d'initialisation (double dans ce cas). Voir une réponse détaillée au programmers.stackexchange.com.

Pour l'instant, votre solution consiste à utiliser la syntaxe non uniforme qui utilise des parenthèses. Cela signifie qu'il ne considérera pas le constructeur std::initializer_list et fera ce que vous voulez dans ce cas.

std::vector<double> bestScores(s, -1.0)

Questions connexes