web-dev-qa-db-fra.com

Conversion implicite non autorisée au retour

#include <optional>

bool f() {
  std::optional<int> opt;
  return opt;
}

Ne compile pas: 'return': cannot convert from 'std::optional<int>' to 'bool'

Consultation de référence J'aurais pensé trouver une explication, mais je l'ai lu comme il se doit.

Des conversions implicites sont effectuées chaque fois qu'une expression d'un certain type T1 est utilisée dans un contexte qui n'accepte pas ce type, mais accepte un autre type T2; en particulier:

  • lorsque l'expression est utilisée comme argument lors de l'appel d'une fonction déclarée avec T2 comme paramètre;
  • lorsque l'expression est utilisée comme opérande avec un opérateur qui attend T2;
  • lors de l'initialisation d'un nouvel objet de type T2, y compris l'instruction de retour dans une fonction renvoyant T2;
  • lorsque l'expression est utilisée dans une instruction switch (T2 est de type intégral);
  • lorsque l'expression est utilisée dans une instruction if ou une boucle (T2 est booléen).
21
darune

Il ne s'agit pas vraiment de conversion implicite, mais du type d'initialisation.

Ce qui est facultatif est une fonction de conversion explicite, c'est-à-dire.

explicit operator bool() const; 

Depuis N4849 [class.conv.fct]/p2

Une fonction de conversion peut être explicite (9.2.2), auquel cas elle n'est considérée que comme une conversion définie par l'utilisateur pour l'initialisation directe.

Ce qui précède signifie que ces cas utiliseront la fonction de conversion: [dcl.init]/p16

L'initialisation qui se produit (16.1) - pour un initialiseur qui est une liste d'expressions entre parenthèses ou une liste d'initialisation entre accolades, (16.2) - pour un nouvel initialiseur (7.6.2.7), (16.3) - dans une expression static_cast ( 7.6.1.8), (16.4) - dans une conversion de type de notation fonctionnelle (7.6.1.3) et (16.5) - sous la forme de liste d'initialisation entre accolades d'une condition est appelée initialisation directe.

Cependant, ces cas n'utiliseront pas la fonction de conversion: [dcl.init]/p15

L'initialisation qui se produit sous la forme = d'un initialiseur d'accolade ou d'égalité ou d'une condition (8.5), ainsi que dans le passage d'argument, le retour de fonction, le lancement d'une exception (14.2), la gestion d'une exception (14.4) et l'initialisation d'un membre (9.4.1), est appelée initialisation de copie.

L'exemple de la question relève du cas d'initialisation de copie et n'utilise pas la fonction de conversion optionnelle.

1
Trixie