Question

Après une lecture approfondie de ISO/IEC 14882, Langage de programmation – C++ Je ne sais toujours pas pourquoi const est nécessaire pour la conversion implicite en un type défini par l'utilisateur avec un constructeur à argument unique comme celui-ci

#include <iostream>

class X {
public:
   X( int value ) {
      printf("constructor initialized with %i",value);
   }
}

void implicit_conversion_func( const X& value ) {
   //produces "constructor initialized with 99"
}

int main (int argc, char * const argv[]) {
   implicit_conversion_func(99);
}



À partir de la section 4, ligne 3

Une expression e peut être implicitement convertie en un type T si et seulement si la déclaration T t=e ;est bien formé, pour une variable temporaire inventée t (8.5).Certaines constructions de langage nécessitent qu'une expression soit convertie en valeur booléenne.Une expression e apparaissant dans un tel contexte est dite contextuellement convertie en bool et est bien formée si et seulement si la déclaration bool t(e);est bien formé, pour une variable temporaire inventée t (8.5).L'effet de l'une ou l'autre conversion implicite est le même que celui d'effectuer la déclaration et l'initialisation, puis d'utiliser la variable temporaire comme résultat de la conversion.Le résultat est une lvalue si T est un type de référence lvalue (8.3.2), et une rvalue dans le cas contraire.L'expression e est utilisée comme lvalue si et seulement si l'initialisation l'utilise comme lvalue.

Suite à cela, j'ai trouvé la section sur les initialiseurs liés aux types définis par l'utilisateur dans 8.5 ligne 6

Si un programme appelle l'initialisation par défaut d'un objet d'un type T qualifié par const, T doit être un type de classe avec un constructeur par défaut fourni par l'utilisateur.

Finalement, je me suis retrouvé à la ligne 2 de 12,3 sur les conversions définies par l'utilisateur qui indique

Les conversions définies par l'utilisateur sont appliquées uniquement lorsqu'elles sont sans ambiguïté (10.2, 12.3.2).

Inutile de dire que les versions 10.2 et 12.3.2 n'ont pas répondu à ma question.

  1. Quelqu'un peut-il nous éclairer sur l'effet const a sur les conversions implicites ?
  2. L'utilisation de const rendre la conversion « sans ambiguïté » selon 12,3 ligne 2 ?
  3. Fait const affecter d'une manière ou d'une autre lvalue vs.rvalue évoquée dans la section 4 ?
Était-ce utile?

La solution

Cela n'a pas vraiment grand chose à voir avec la conversion implicite.De plus, cela n'a pas grand chose à voir avec conversions.Il s'agit vraiment de valeurs contre. lvaleurs.

Quand vous convertissez 99 taper X, le résultat est un rvaleur.En C++, les résultats des conversions sont toujours des rvalues ​​(sauf si vous convertissez en type référence).Il est illégal en C++ d'attacher des références non const aux rvalues.

Par exemple, ce code ne compilera pas

X& r = X(99); // ERROR

car il tente d'attacher une référence non const à une rvalue.Par contre, ce code est bien

const X& cr = X(99); // OK

car il est parfaitement acceptable d'attacher une référence const à une rvalue.

La même chose se produit également dans votre code.Le fait que cela implique une conversion implicite est un peu hors de propos.Vous pouvez remplacer la conversion implicite par une conversion explicite

implicit_conversion_func(X(99));

et on se retrouve avec la même situation :avec const il compile, sans const ce n'est pas le cas.

Encore une fois, le seul rôle que joue ici la conversion (explicite ou implicite) est qu’elle nous aide à produire une rvalue.En général, vous pouvez produire une rvalue d'une autre manière et rencontrer le même problème

int &ir = 3 + 2; // ERROR
const int &cir = 3 + 2; // OK

Autres conseils

Par section 5.2.2 paragraphe 5, lorsqu'un argument d'une fonction est de type référence const, une variable temporaire est introduit automatiquement si nécessaire. Dans votre exemple, le résultat rvalue de X(99) doit être mis dans une variable temporaire de telle sorte que cette variable peut être transmis par référence à const implicit_conversion_func.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top