60 votes

Pourquoi le nombre d'éléments dans une liste d'initialisation provoque-t-il une erreur d'appel ambigu?

Pourquoi les deux premiers appels à doSomething acceptés par le compilateur, mais l'utilisation de deux éléments de la liste entraîne un appel ambigu?

 #include <vector>
#include <string>

void doSomething(const std::vector<std::string>& data) {}

void doSomething(const std::vector<int>& data) {}

int main(int argc, char *argv[])
{
    doSomething({"hello"}); // OK
    doSomething({"hello", "stack", "overflow"}); // OK
    doSomething({"hello", "stack"}); // C2668 'doSomething': ambiguous call

    return 0;
}
 

62voto

NathanOliver Points 10062

Ce qui se passe ici est que, dans les deux élément d'initialiseur de liste à la fois des littéraux de chaîne peut être implicitement converti en const char* depuis leur type const char[N]. Maintenant, std::vector a un constructeur qui prend deux itérateurs qui les pointeurs de se qualifier pour. Parce que l' initializer_list constructeur de la std::vector<std::string> est en conflit avec l'itérateur de la gamme du constructeur de l' std::vector<int>.

Si nous modifions le code au lieu d'être

doSomething({"hello"s, "stack"s});

Ensuite, les éléments de la liste d'initialiseur sont désormais std::strings, donc il n'y a pas d'ambiguïté.

23voto

Quentin Points 3904

Les listes à un argument et à trois arguments ne peuvent correspondre qu'au constructeur std::vector<std::string> 's std::initializer_list . Cependant, la liste à deux arguments correspond à l'un des constructeurs de std::vector<int> :

 template <class InputIt>
vector(InputIt first, InputIt last, Allocator const &alloc = Allocator());
 

En effet, un char const * peut être incrémenté et déréférencé pour obtenir un char convertible implicitement en int .

17voto

François Andrieux Points 16034

"hello" et "stack" décroissent tous les deux en const char * ce qui correspond au concept InputIterator . Cela leur permet de faire correspondre le constructeur # 4 de std::vector .

Si vous transmettez des objets std::string , l'ambiguïté est résolue.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X