Domanda
Di recente ho giocato con il linguaggio D e ho una domanda veloce sui template.
Sto inserendo caratteri e stringhe in una stringa esistente nel codice e ho creato questa funzione:
string insert(T)(string s1, T s2, uint position) {
return s1[0 .. position] ~ s2 ~ s1[position .. $];
}
Ora ho diverse domande.
-
Posso limitare i tipi consentiti per l'argomento s2 (voglio solo char, wchar, dchar, ecc. e i loro rispettivi valori di array)?
-
Esiste un modo per definire il modello per sapere automaticamente di anteporre se la posizione arg è 0? Qualcosa del genere (che non viene compilato, ma dà l'idea generale):
string insert(T)(string s1, T s2, uint position) { static if (position == 0) return "" ~ s2 ~ s1; else return s1[0 .. position] ~ s2 ~ s1[position .. $]; }
Grazie
Soluzione
- Sì - utilizzando specializzazione dei parametri del modello o vincoli di modello (equivalente di concetti C ++ 1x).
-
statico se
implica che la condizione può essere calcolata al momento della compilazione. Un parametro di funzione non può essere, quindi usa unif
normale o impostaposition
un parametro template.
Altri suggerimenti
Per 1, in realtà ci sono due posti in cui puoi limitare i tipi consentiti.
Il primo è prima della selezione del metodo. Se un simbolo si risolve in più metodi, il compilatore tenterà di eliminarne il maggior numero possibile prima di dover provare a decidere quale utilizzare. I vincoli del modello (solo D2) e la specializzazione funzionano in questa fase. Ad esempio:
string insert(T)(string s1, T s2, uint position) if(isSomeChar!T) // D2 only
-o -
string insert(T : dchar)(string s1, T s2, uint position) // D1 or D2
L'altro è dopo selezione del metodo. È qui che il compilatore ha già deciso di utilizzare questo metodo specifico. Puoi farlo con assert statici. Tieni presente che ciò non fa andare il compilatore " ooh; Dovrei provare a cercare un sovraccarico diverso! & Quot ;; si arrenderà semplicemente.
string insert(T)(string s1, T s2, uint position)
{
static if( !isSomeChar!(T) )
{
pragma(msg, "Error: insert(T): T must be a character type.");
static assert(false);
}
...
}
Un'altra cosa: per quanto ne so, ** non puoi * concatenare semplicemente wchars e dchars in una stringa (che è un array di caratteri). Dovrai prima codificare il carattere in una stringa. encode
nel modulo std.utf
dovrebbe fare il trucco.
Quanto al 2, non puoi semplicemente usare una normale istruzione if?