Tout d'abord, la conversion de la séquence de tous les trois est la même, sauf que pour les deux premiers, il y a une lvalue transformation (lvalue à rvalue de conversion), qui n'est cependant pas utilisé dans la commande de conversion de séquences. Tous les trois sont des correspondances exactes (le modèle de fonction de la spécialisation a type de paramètre char const(&)[2]
).
Si vous parcourez les règles de l' 13.3.3.2p3
, vous vous arrêtez à ce paragraphe
S1 et S2 sont référence des liaisons (8.5.3) et ne se réfère à un objet implicite paramètre de non-fonction membre statique déclarée sans ref-qualificatif, et S1 lie référence rvalue à une rvalue et S2 lie une lvalue de référence.
Une conversion de la séquence ne peut pas être formée si elle nécessite une liaison référence rvalue à une lvalue, la spec dit à 13.3.3.1.4p3. Si vous regardez comment la référence de la liaison fonctionne à 8.5.3p5 dernière balle, il va créer un temporaire (je pense qu'ils voulaient dire rvalue temporaire) de type char const*
à partir de la matrice de lvalue et lier la référence que temporaire. À cet effet, je pense que (1)
est mieux que (2)
. De même pour (1)
contre (3)
, bien que nous n'aurions pas besoin de cela, car (3)
est un modèle de sorte à égalité, nous choisirions (1)
de nouveau.
En n3225
, ils ont changé la référence des règles contraignantes afin que les références rvalue peut se lier à l'initialiseur expressions qui sont lvalues, tant que la référence soit lié à une rvalue (peut-être créé par la conversion de l'initialiseur correctement avant). Cela pourrait influencer le traitement par Visual C++, qui peut ne pas être à jour ici.
Je ne suis pas sûr de clang. Même si il serait ignorer (1)
, alors qu'il finirait dans une égalité entre (2)
et (3)
, et aurait besoin de choisir (2)
parce que c'est un non-modèle.
Je pense que 8.5.3p5 dernier point est source de confusion car il est dit "dans le cas Contraire temporaire de type...". Il n'est pas clair si le temporaire est considéré comme une lvalue ou comme une rvalue par 13.3.3.1.4p3, ce qui signifie que je ne suis pas sûr de savoir comment les points suivants devraient vraiment se comporter selon les mots exacts de la spec
void f(int &);
void f(int &&);
int main() {
int n = 0;
f(n);
}
Si nous supposons que le temporaire est considérée comme une rvalue par l'article 13, puis nous lier une rvalue ref à une rvalue dans la seconde fonction et une lvalue dans la première. À cet effet, nous allons choisir la deuxième fonction, et ensuite obtenir un diagnostic de 8,5.3p5 dernier point, car T1
et T2
sont des références relatives. Si nous supposons que le temporaire est considérée comme une lvalue par l'article 13, puis le suivant ne marche pas
void f(int &&);
int main() {
f(0);
}
Parce que nous lient une rvalue ref à une lvalue qui, par la clause 13 fera la fonction non-viable. Et si nous interpréter "de la liaison à une rvalue ref à une lvalue" pour se référer à l'initialiseur d'expression à la place de l'expression finale lié à l', nous n'accepterons pas les suivants
void f(float &&);
int main() {
int n = 0;
f(n);
}
Ceci, toutefois, est valable à compter de n3225. Il semble donc y avoir une certaine confusion - j'ai envoyé un DR à la commission à ce sujet.