Dans la norme C++, §13.3.1.7 [plus.match.liste], comme indiqué:
Dans la copie de la liste d'initialisation, si un
explicit
constructeur est choisi, l'initialisation est mal formé.
C'est la raison pour laquelle nous ne pouvons pas faire, par exemple, quelque chose comme ceci:
struct foo {
// explicit because it can be called with one argument
explicit foo(std::string s, int x = 0);
private:
// ...
};
void f(foo x);
f({ "answer", 42 });
(Notez que ce qui se passe ici n'est pas une conversion, et il ne serait pas même si le constructeur était "implicite". C'est l'initialisation de foo
objet à l'aide de son constructeur directement. Autres que l' std::string
, il n'y a pas de conversion ici.)
Cela semble parfaitement bien pour moi. Il n'y a aucun moyen de faire une conversion implicite va me mordre.
Si { "answer", 42 }
pouvez initialiser quelque chose d'autre, le compilateur ne pas me trahir et faire la mauvaise chose:
struct bar {
// explicit because it can be called with one argument
explicit bar(std::string s, int x = 0);
private:
// ...
};
void f(foo x);
void f(bar x);
f({ "answer", 42 }); // error: ambiguous call
Il n'y a pas de problème: l'appel est ambigu, le code ne compile pas, et je vais avoir à prendre la surcharge explicitement.
f(bar { "answer", 42 }); // ok
Depuis l'interdiction est explicitement indiqué, j'ai l'impression qu'il me manque quelque chose ici. Aussi loin que je peux voir, initialisation de la liste de la cueillette explicite les constructeurs ne semble pas être un problème pour moi: à l'aide de la liste d'initialisation de la syntaxe, le programmeur est déjà exprimé le désir de faire une sorte de "conversion".
Ce qui pourrait aller mal? Ce qui me manque?