2012-05-02 16 views
5

Esiste un modo per implementare stringhe che funzionino sia in fase di compilazione che in fase di esecuzione?C++ 11 implementazione della stringa constexpr

AFAIK per una classe da costruire in constexpr è necessario avere un distruttore banale. Tuttavia, questo si rivela difficile quando abbiamo a che fare con stringhe. Se la stringa NON è constexpr, allora ha bisogno di deallocare la memoria. Tuttavia, se è constexpr, allora viene assegnato staticamente e non dovrebbe essere cancellato, consentendo così un distruttore banale.

Tuttavia, non è possibile dire "Ehi, compilatore! Se sono constexpr, non è necessario distruggermi!" O è?

Sarebbe qualcosa di simile al seguente:

class string { 
private: 
    char * str; 
public: 
    template<std::size_t l> 
    constexpr string(const char (&s)[l]) : str(&(s[0])) {} 
    string(const char * s) { str = strdup(s); } 
    static if (object_is_constexpr) { 
     ~string() = default; 
    } 
    else { 
     ~string() { free(str); } 
    } 
}; 

Il più vicino che ho potuto venire sta avendo due tipi distinti, corda e constexpr_string, un constexpr_string _string letterale definito dall'utente di ritorno, e un utente conversione implicita definita da constexpr_string a stringa.

Questo non è molto bello però, come const auto s = "asdf"_string; funziona ma non lo è const string s = "asdf"_string;. Inoltre, un riferimento/puntatore a constexpr_string non verrà convertito. L'ereditarietà, in entrambi i casi, causa "intuizioni" non intuitive e non risolve il primo problema.

Sembra che dovrebbe essere possibile, purché il compilatore dovesse FIDUCIA il programmatore che il constexpr non ha bisogno di essere distrutto.

Se ho un'idea sbagliata fammelo sapere.

+0

Penso che stiate cercando 'strwrap' da http://akrzemi1.wordpress.com/2011/05/11/parsing-strings-at-compile-time-part-i/ – Cubbi

+0

String letterali' const char (& Var) [N] '_ are_ il tipo di stringa' constexpr'. –

+1

Devi amare quando le persone iniziano a utilizzare funzioni come 'static if' prima che vengano approvate! –

risposta

9

Non è solo una questione di distruzione.

Un'operazione constexpr deve solo chiamare altre constexpr operazioni e new, malloc ecc ... sono nonconstexpr. Si noti che questa è una proprietà staticamente controllata e non dipende dall'argomento runtime, quindi la chiamata a tale funzione deve essere completamente assente e non semplicemente nascosta in un ramo che (presumibilmente) non è stato preso.

Come tale, non sarà mai possibile ottenere constexprstring.

+0

Non può nemmeno essere in un costruttore non constexpr?Sembra che sia possibile avere entrambi i costruttori constexpr e non-constexpr per un dato tipo, così come è possibile avere metodi const e non-const. –

+0

È possibile creare totalmente un tipo di stringa 'constexpr', non sarà in grado di gestire le stringhe non-constexpr. Basta fare le funzioni di conversione. –

+0

Il modo in cui lo vedo, constexpr è un modo per sfumare la linea tra il tempo di compilazione e il calcolo del tempo di esecuzione. I tipi primitivi lo consentono e sembra che sia possibile fare alcune cose per consentire ai puntatori nelle classi di puntare a una memoria allocata letteralmente o dinamicamente. I linguaggi funzionali si sono estrapolati per un certo tempo al limite del tempo di compilazione/runtime. @Mooing Duck: le funzioni di conversione sembrano rompere l'astrazione –

0

È possibile, in una certa misura, vedere the code example in this page. È possibile creare oggetti constexpr conststr e richiamare alcune operazioni su di essi, ma non è possibile utilizzarli come parametri modello di tipo non.

Problemi correlati