2013-04-05 5 views
6

J'ai deux ou trois classes filiformes qui peuvent être convertis de façon implicite à cordes. J'ai quelques utilisations pour ceux-ci; un exemple est de contenir du texte qui doit être traduit à l'exécution par gettext:chaîne comme ++ C classe avec conversion implicite

class TranslatableString 
{ 
public: 
    explicit TranslatableString(const char *s) : native_text_(s) {} 
    operator const char *() const { return gettext(native_text_); } 

    // Or not - see below: 
    operator const std::string() const { return gettext(native_text_); } 

private: 
    const char * const native_text_; 
}; 

Maintenant, je suis en train de faire en utilisant cette classe aussi simple que possible (par exemple, son utilisation doit être aussi un peu comme une chaîne littérale possible). En particulier, je voudrais que les deux usages des exemples suivants pour travailler:

const TranslatableString HELLO = TranslatableString("Hello, world!"); 

std::string ExampleA() { 
    return HELLO; 
} 

void ExampleB() { 
    std::string s; 
    s = HELLO; 
} 

Est-il possible de faire les deux exemples fonctionnent-ils?

  • Si je operator std::string inclus, alors ExampleB ne parvient pas à compiler, en disant qu'il ya une ambiguïté entre std::string::operator=(const char *) et std::string operator=(const std::string&) (ce qui est logique).
  • Si je n'inclue pas operator std::string, alors ExampleA ne peut pas être compilé; la conversion apparemment implicite d'un TranslatableString en const char * en std :: string n'est pas autorisée, bien que je ne comprenne pas assez bien les règles de conversion implicite de C++ pour expliquer pourquoi.

Répondre

5

Une seule conversion définie par l'utilisateur est autorisée dans chaque séquence de conversion, c'est pourquoi vous ne pouvez pas passer à travers const char*. (Notez que const char* à std::string est également une conversion définie par l'utilisateur).

Avez-vous besoin de la conversion à const char*? Sans cela (et avec la conversion en std::string), les deux exemples fonctionneraient.

Il peut également être utile d'envisager de stocker les données en tant que std::string en interne, au lieu de const char*. Vous ne devriez pas vous inquiéter des problèmes de désallocation, les données "disparaissent" sous vos mains, etc.

+0

Fait sens. Merci. (Cette classe particulière est uniquement conçue pour être utilisée avec des littéraux de chaîne, donc 'const char *' est correct, ailleurs, j'utilise presque toujours 'std :: string'.) –

1

Vous devrez abandonner pour avoir operator const char *. Faites-le explicit (C++ 11) ou fournissez-le comme méthode c_str à la place.

La conversion de TranslatableString en const char * en std::string n'est pas autorisée car elle contient deux conversions définies par l'utilisateur.