2012-03-09 23 views
5

に送信します。関数のテンプレート引数としてDのsort関数を送信しようとしています。私はそれが動作テンプレート引数なしでsortを使用する場合: テンプレート関数をテンプレート関数の引数としてD

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

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

私はテンプレート引数でsortを使用しようとするただし、:

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

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

私はエラーを取得する - 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)

それはなぜ起こるのですか? sort!"b<a"はそれ自体で動作し、同じ引数と戻り値の型をsortとしています。なぜpipesortを受け取りますが、sort!"b<a"を受け入れないのですか?そして、私がしようとしているものに対して正しい構文がありますか?

UPDATE

OK、私はsort機能をラップしようとしました。次のコードは動作します:

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

なぜ元のバージョンは動作しませんか?これは余分なテンプレートのパラメータのためですsortがかかりますか?

答えて

5

はい、特別なテンプレートパラメータ、具体的にはRangeパラメータが原因です。問題は

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

の範囲が決定されていないためsort!"b<a"が失敗するインスタンス化を減少させることができます。ファンクションコールsort2!"b<a"([1,2,3])は、パラメータ[1,2,3]がタイプRangeがint[]であることをコンパイラに伝えることができるため機能します。これは「暗黙的関数テンプレートのインスタンス化(IFTI)」として知られています。しかしIFTIは、それが関数として使用されている場合にのみ動作します。ユースケースでは、すべてのパラメータを指定せずにsort!"b<a"がインスタンス化されるため、エラーが発生します。

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

それとも、必要なすべてのテンプレートパラメータを提供することができます:

これは、入力あなたのmysortソリューションにちょうど似ている関数リテラルを作ることによって固定することができます。これにより、コードは非常に判読不能になります。私は...私は、暗黙的にテンプレートパラメータとして引数の型のget、最初にそのパラメータを渡す必要があり、 `pipe`テンプレートを考え出し参照

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

は、機能をパイプが、私はそうではありません参照してください。 –

+0

@IdanArye: 'pipe'は、それを引数(' alias pipe!(f)piped;)から分離し、その後に 'piped([1,2,3]);') – kennytm

+0

テンプレート化された関数自体を 'piped'するような' alias'をしてはいけませんか? –

関連する問題