2012-03-09 18 views
5

Estoy intentando enviar la función D's sort como argumento de plantilla a la función pipe. Cuando uso sort sin argumentos de plantilla funciona: Enviar una función de plantilla como argumento a una función de plantilla en D

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

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

Sin embargo, cuando intento utilizar sort con un argumento de plantilla:

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

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

Me aparece un error - 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)

¿Por que sucede? sort!"b<a" funciona por sí mismo, y tiene los mismos argumentos y tipos de devolución que sort, entonces ¿por qué pipe acepta sort pero no sort!"b<a"? ¿Y hay una sintaxis correcta para lo que trato de hacer?

ACTUALIZACIÓN

bien, he tratado de englobar la función sort. El siguiente código funciona:

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

¿Por qué no tiene la versión de la obra original? ¿Esto es debido a los parámetros adicionales de la plantilla sort?

Respuesta

5

Sí, es debido a los parámetros adicionales de la plantilla, específicamente el parámetro Range. El problema puede reducirse a

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

la creación de instancias sort!"b<a" se producirá un error debido a que el rango no está determinada. La llamada a la función sort2!"b<a"([1,2,3]) funciona porque el parámetro [1,2,3] le puede decir al compilador que el tipo Range es int[]. Esto se conoce como "instanciación de plantilla de función implícita (IFTI)". Pero IFTI solo funciona cuando se usa como una función. En su caso de uso, sort!"b<a" se crea una instancia sin proporcionar todos los parámetros, por lo tanto el error.

Esto se puede solucionar haciendo que la entrada de un literal de la función, que es sólo similar a la solución de mysort:

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

o podría proporcionar todos los parámetros de plantilla necesarios. Esto hace que el código sea muy ilegible.

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

veo ... pensé que la plantilla 'pipe', que implícitamente obtener es el tipo del argumento como un parámetro de plantilla, debe pasar ese parámetro para la primera función de hilo, pero veo que no es el caso. –

+0

@IdanArye: 'pipe' nunca puede hacer eso, porque uno podría separarlo del argumento (' alias pipe! (F) hilo; 'y luego muchas líneas más adelante' hilo ([1,2,3]); ') – kennytm

+0

¿No debería 'alias'ing así hacer de' piped' una función de plantilla en sí misma? –

Cuestiones relacionadas