2013-04-05 5 views
6

Ho un paio di classi stringhe che possono essere convertite implicitamente in stringhe. Ho alcuni usi per questi; Un esempio è quello di tenere il testo che deve essere tradotto in fase di esecuzione gettext:Classe tipo stringa C++ con conversione implicita

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_; 
}; 

Ora sto cercando di fare con questa classe il più semplice possibile (cioè, il suo utilizzo dovrebbe essere tanto come una stringa letterale come possibile). In particolare, mi piacerebbe che entrambi i seguenti esempi di utilizzo funzionassero:

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

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

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

C'è un modo per far funzionare entrambi gli esempi?

  • Se includo operator std::string, poi ExampleB non riesce a compilare, dicendo che c'è un'ambiguità tra std::string::operator=(const char *) e std::string operator=(const std::string&) (che ha un senso).
  • Se non includo operator std::string, Esempio Impossibile compilare; la trasformazione apparentemente implicita di TranslatableString in const char * in std :: string non è consentita, anche se non capisco le regole di conversione implicite del C++ abbastanza bene da spiegare il perché.

risposta

5

Solo una conversione definita dall'utente è consentita in ogni sequenza di conversione, ecco perché non è possibile passare "attraverso" a const char*. (Si noti che const char* a std::string è anche una conversione definita dall'utente).

Hai bisogno della conversione in const char*? Senza di esso (e con la cover allo std::string), entrambi gli esempi funzionerebbero.

Potrebbe anche essere utile memorizzare i dati come std::string internamente, anziché const char*. Non dovresti preoccuparti dei problemi di deallocazione, i dati "spariscono" sotto le tue mani ecc.

+0

Ha senso. Grazie. (Questa particolare classe è progettata solo per essere utilizzata con stringhe letterali, quindi 'const char *' va bene, in altri casi, quasi sempre uso 'std :: string'.) –

1

Dovrai rinunciare ad avere operator const char *. Rendilo explicit (C++ 11) o forniscilo come metodo c_str.

La conversione da TranslatableString a const char * a std::string non è consentita in quanto contiene due conversioni definite dall'utente.