Question

J'ai un modèle défini ci-dessous afin que je puisse effectuer un casting explicite, mais sûre:

/// cast using implicit conversions only
template <class To,class From>
inline To safe_cast( const From &from ) {return from;}

Foire (par exemple lors du passage des arguments en sprintf et des fonctions similaires) Je voudrais utiliser ce modèle pour effectuer une conversion d'une classe de chaîne à une chaîne de style c. Cependant, il montre cela est impossible quand est passé temporaire, parce que le temporaire ne vivrai pas assez longtemps.

Prenons l'exemple suivant:

class Object
{
  public:
  MyStringClass GetDebugName() const;
};

Object obj;
printf("%s",safe_cast<const char *>(obj.GetDebugName()));

Le temporaire obj.GetDebugName () ne vit que pendant la safe_cast et le pointeur est invalide (des points aux données de la chaîne temporaire qui a déjà été détruits) lorsque l'intérieur du printf.

Pour contourner ce problème, je un moment à l'aide coulée directe sans appel de modèle: const char *c = (const char *)(obj.GetDebugName(), mais cela a un inconvénient de sécurité de type réduite, que la distribution est inutilement forte (par exemple, il serait silencieusement réussir même si obj.GetDebugName () serait retour int au lieu d'une valeur de chaîne). static_cast peut-être un peu mieux, mais même cela est trop fort, je voudrais faire une erreur sur toute situation où cast est pas sûr d'être en sécurité.

1) Si je ne me trompe pas, la norme indique la durée de vie temporaire est une déclaration (à moins prolongée par être lié à une référence const, auquel cas il est la durée de vie de la référence). Lorsque l'on regarde l'exemple de printf ci-dessus, je ne suis pas tout à fait sûr de ce que une « déclaration » est, et si le comportement que je l'ai vu est ou non conforme. Si l'instruction est l'ensemble printf, la durée de vie de la const & de est plus courte - quelle vie dois-je attendre du temporaire? Quelqu'un peut-il préciser?

2) Y at-il une autre façon de faire une conversion qui serait en sécurité, mais le résultat serait assez longtemps pour être utile?

Edit:

S'il vous plaît, considérez ceci plus une sorte de question générale, je suis à la recherche d'un mécanisme comment une conversion comme celui-ci à faire en ce qui concerne la durée de vie temporaire, je ne suis pas beaucoup intéressé par un cas particulier d'une chaîne particulière classe.

Pour expliquer pourquoi je ne veux pas utiliser .c_str ou une fonction membre similaire: Je voudrais que le code de conversion pour être agnostique type, je ne veux pas le code de compter sur le fait que je sais que ce type de chaîne particulière a c_str mis en œuvre, je veux travailler, même si une autre classe de chaîne serait retourné par ObjectDebugName, ou même si ObjectDebugName serait déjà de retour const char * (ce qui exclut la possibilité d'appeler .operator const char * ().

Était-ce utile?

La solution

  

Je peux effectuer un casting explicite, mais en toute sécurité

Je l'appellerais une distribution implicite faite explicitement, ou tout simplement et explicite conversion implicite.

  

1) Si je ne me trompe pas, la norme indique la durée de vie temporaire est une déclaration (à moins prolongée par être lié à une référence const, auquel cas il est la durée de vie de la référence). Lorsque l'on regarde l'exemple de printf ci-dessus, je ne suis pas tout à fait sûr de ce que une « déclaration » est, et si le comportement que je l'ai vu est ou non conforme. Si l'instruction est l'ensemble printf, la durée de vie de la const & de est plus courte - quelle vie dois-je attendre du temporaire? Quelqu'un peut-il préciser?

Vous avez raison, le temporaire est détruit après printf've retourné. Le code que vous avez fourni devrait fonctionner. Si elle ne le fait pas, cela signifie que vous misprovided des informations importantes.

Autres conseils

Je ne sais pas pourquoi vous utilisez votre propre classe de chaîne ici. Est-ce que la classe a une fonction membre pour obtenir le const char * en sortir?

std :: string GetDebugName ();

printf ( "% s", GetDebugName () c_str ().);

serait en sécurité comme temporaire restent valables pendant cette déclaration, par exemple.

Vous pouvez appeler la fonction de conversion directe:

printf("%s", obj.GetDebugName().operator const char*());
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top