C++ conversions implicites
Plusieurs commentaires sur une récente réponse de la mine, Ce que d'autres moulages peuvent être utilisés en C++, suggèrent que ma compréhension de C++ conversions est défectueux. Juste pour clarifier la question, considérons le code suivant:
#include <string>
struct A {
A( const std::string & s ) {}
};
void func( const A & a ) {
}
int main() {
func( "one" ); //error
func( A("two") ); //ok
func( std::string("three") ); //ok
}
Mon affirmation était que le premier appel de fonction est une erreur, becauuse il n'y a pas de conversion à partir d'un const char * à un A. Il y a une conversion d'une chaîne en Un, mais en utilisant cela impliquerait plus d'une conversion. Ma compréhension est que ce n'est pas autorisé, et ce qui semble être confirmé par g++ 4.4.0 & Comeau compilateurs. Avec Comeau, j'obtiens l'erreur suivante:
"ComeauTest.c", line 11: error: no suitable constructor exists
to convert from "const char [4]" to "A"
func( "one" ); //error
Si vous pouvez le remarquer, où je me trompe, que ce soit ici ou dans la réponse originale à cette question, de préférence avec une référence à la Norme C++, merci de le faire.
Et la réponse de la norme C++ semble être:
Au plus une conversion définie par l'utilisateur
(constructeur ou de la fonction de conversion)
est implicitement appliqué à une valeur unique.
Grâce à Abhay pour fournir le devis.
- Je suis désolé, j'étais mal dans le commentaire à votre réponse. J'ai lu "la résolution de Surcharge est utilisé pour sélectionner la conversion définie par l'utilisateur pour être invoqué.", et je me suis dit: "eh bien, alors il va se résoudre à Un(string const&) et la passer "un"', mais j'ai totalement omis de penser à ce que 13.3.3.1.2 dit: "Une conversion définie par l'utilisateur de la séquence se compose d'une norme initiale de la conversion de la séquence suivie d'une conversion définie par l'utilisateur (12.3), suivie par une deuxième conversion standard de la séquence." Mais "on" -> string ne serait pas une conversion standard de la séquence, mais demander à un autre utilisateur de conversion définis par la séquence de!
- Juste aussi longtemps que je ne suis pas à perdre mes billes 🙂
- Excellente question! La discussion implique que
std::string
ne fait pas partie de la langue et de conversions vers/depuis qu'il sont "définies par l'utilisateur". Au moins, c'est ma compréhension, corrigez-moi si je me trompe. Ce serait bien si la question ont été plus explicite à ce sujet. Statut Exact destd::string
peut être de cristal clair, vieux C++ mains, mais n'est pas si facile à réaliser pour les personnes qui sont venus à la langue dans ce siècle. - Est - il Correct, std::string est juste une bibliothèque de classe, vous pouvez écrire à l'identique à elle-même, de sorte que la langue ne spécifiez pas de tout traitement spécial pour elle.
Vous devez vous connecter pour publier un commentaire.
Je pense que la réponse de déchainée est précis. La Norme C++ (SC22-N-4411.pdf) section 12.3.4 intitulé "Conversions", montre clairement qu'un seul implicite de conversion définie par l'utilisateur est autorisé.
Que le consensus semble être déjà: oui, vous avez raison.
Mais comme cette question /réponses vont probablement devenir le point de référence pour le C++ conversions implicites sur stackoverflow, je tiens à ajouter que pour les arguments de modèle les règles sont différentes.
Pas de conversions implicites sont autorisés pour les arguments qui sont utilisés pour l'argument de modèle de déduction. Cela pourrait paraître assez évident mais peuvent néanmoins conduire à de subtiles étrangeté.
Cas au point, std::string outre, les opérateurs
(1) compile et fonctionne très bien,
operator+=
est une fonction membre, le modèle de paramètre de caractère est déjà déduite par l'instanciation destd::string
de s (àchar
). Donc les conversions implicites sont autorisés (int
->char
), les résultats de s contenant le char de l'équivalent de 67, par exemple en ASCII ce qui allait devenir "C"(2) donne une erreur de compilation, comme
operator+
est déclarée comme une fonction libre, et ici, le modèle de caractère argument est utilisé en déduction.C'est vrai, un seul implicite la conversion est possible.
Deux conversions en ligne peut être effectuée avec une combinaison d'un opérateur de conversion et un constructeur paramétré mais cela provoque un C4927 avertissement - "la conversion illégale; plus d'une conversion définie par l'utilisateur a été implicitement appliqué" - dans VC++ pour une raison.
Le Langage De Programmation C++ (4ème. ed.) (section 18.4.3) dit que
Que "défini par l'utilisateur" partie le fait ressembler à de multiples conversions implicites peuvent être autorisés si certains sont entre les types natifs.