2012-03-09 16 views
5

Sto tentando di inviare la funzione D sort come argomento modello alla funzione pipe. Quando uso sort senza argomenti template funziona: Invio di una funzione basata su modello come argomento a una funzione basata su modelli in D

import std.stdio,std.algorithm,std.functional; 

void main() 
{ 
    auto arr=pipe!(sort)([1,3,2]); 
    writeln(arr); 
} 

Tuttavia, quando si tenta di utilizzare sort con un argomento modello:

import std.stdio,std.algorithm,std.functional; 

void main() 
{ 
    auto arr=pipe!(sort!"b<a")([1,3,2]); 
    writeln(arr); 
} 

ottengo un errore - main.d(5): Error: template instance sort!("b<a") sort!("b<a") does not match template declaration sort(alias less = "a < b",SwapStrategy ss = SwapStrategy.unstable,Range)

Perché succede? sort!"b<a" funziona autonomamente e ha gli stessi argomenti e tipi di ritorno di sort, quindi perché pipe accetta sort ma non sort!"b<a"? E c'è una sintassi corretta per ciò che cerco di fare?

UPDATE

OK, ho cercato di avvolgere la funzione sort. Il seguente codice funziona:

import std.stdio,std.algorithm,std.functional,std.array; 

template mysort(string comparer) 
{ 
    auto mysort(T)(T source) 
    { 
     sort!comparer(source); 
     return source; 
    } 
} 

void main() 
{ 
    auto arr=pipe!(mysort!"b<a")([1,3,2]); 
    writeln(arr); 
} 

Allora, perché non fa il lavoro originale di versione? questo è dovuto ai parametri di modello aggiuntivi sort?

risposta

5

Sì, è a causa dei parametri di modello aggiuntivi, in particolare il parametro Range. Il problema può essere ridotto a

size_t sort2(alias f, Range)(Range range) 
{ 
    return 0; 
} 
alias sort2!"b<a" u; 

l'istanza sort!"b<a" non riuscirà perché la gamma non è determinata. La funzione chiamata sort2!"b<a"([1,2,3]) funziona perché il parametro [1,2,3] può indicare al compilatore che il tipo Intervallo è int[]. Questo è noto come "istanza modello di funzione implicita (IFTI)". Ma IFTI funziona solo quando è usato come una funzione. Nel tuo caso d'uso, sort!"b<a" viene istanziato senza fornire tutti i parametri, quindi l'errore.

Questo può essere risolto facendo l'ingresso di una funzione letterale, che è solo simile alla soluzione mysort:

auto arr = pipe!(x => sort!"b<a"(x))([1,3,2]); 

Oppure si potrebbe fornire tutti i parametri di modello richiesto. Questo rende il codice molto illeggibile.

auto arr = pipe!(sort!("b<a", SwapStrategy.unstable, int[]))([1,3,2]); 
+0

vedo ... ho pensato che il modello 'pipe', che implicitamente ottenere è il tipo di l'argomento come un parametro di template, che dovrebbe passare il parametro per la prima funzione in filodiffusione, ma vedo che non è il caso. –

+0

@IdanArye: 'pipe' non può mai farlo, perché si potrebbe separarlo dall'argomento (' alias pipe! (F) pipeed 'e poi molte righe dopo' piped ([1,2,3]); ') – kennytm

+0

Non dovrebbe 'alias'ing che rende' piped' una funzione basata su un modello stesso? –