problem with template arguments deduction

Dmitry Olshansky dmitry.olsh at gmail.com
Fri Jun 1 04:23:04 PDT 2012


On 01.06.2012 15:16, Zhenya wrote:
> Но тогда почему при замене Bind -> bind
> вот этот код не компилируется?
> module main;
>
> import std.stdio;
> import std.typecons;
> import std.typetuple;
> import std.traits;
>
> template Erase(int k,TList...)
> {
> static if(k != 0)
> alias TypeTuple!(TList[0],Erase!(k-1,TList[1..$])) Erase;
> else
> alias TList[1..$] Erase;
> }
>
> auto Curry(uint i,R,T,U...)(R delegate(U) dg, T arg)
> {
> struct Foo
> {
> typeof(dg) m_dg;
> T m_arg;
> R bar(Erase!(i,U) args)
> {
> U m_args;
> static if(i > 0)
> m_args[0..i] = args[0..i];
> m_args[i] = m_arg;
> static if(i < args.length)
> m_args[i+1..$] = args[i..$];
> return m_dg(m_args);
> }
> }
> Foo* f = new Foo;
> f.m_dg = dg;
> f.m_arg = arg;
> return &f.bar;
> }
>
> template Combination(alias indeces,U...)
> {
> static if(is(typeof(indeces) : int[]))
> {
> static if(indeces.length > 1)
> alias TypeTuple!(U[indeces[0]],Combination!(indeces[1..$],U)) Combination;
> else static if(indeces.length == 1)
> alias TypeTuple!(U[indeces[0]]) Combination;
> }
> }
>
> template update(alias indeces,int current)
> {
> static if(is(typeof(indeces) : int[]))
> {
> static if(indeces.length > 1)
> {
> static if(indeces[0] > current)
> enum int[] update = (indeces[0]-1)~update!(indeces[1..$],current);
> else
> enum int[] update = indeces[0]~update!(indeces[1..$],current);
> }
> else static if(indeces.length == 1)
> {
> static if(indeces[0] > current)
> enum int[] update = [indeces[0]-1];
> else
> alias indeces update;
> }
> }
> }
>
> template Bind(alias indeces)
> {
> static if(is(typeof(indeces) : int[]))
> {
> auto bind(D,V...)(D dg,V values)
> {
> static if(is(D d : R delegate(U), R, U...) &&
> is(V == Combination!(indeces,ParameterTypeTuple!D)))
> {
> static if(indeces.length > 1)
> return
> Bind!(update!(indeces,indeces[0])[1..$]).bind(Curry!(indeces[0])(dg,values[0]),values[1..$]);
>
> else static if(indeces.length == 1)
> return Curry!(indeces[0])(dg,values[0]);
> }
> }
> }
> }
>
> void main()
> {
> void checker(T...)(T args)
> {
> foreach(i,current;args)
> {
> writeln("x",i," = ",current);
> }
> }
> Bind!([1,0,3]).bind(&checker!(int,int,int,int),2,1,4)(3);

Может все-таки
Bind!([1,0,3], &checker!(int, int, int, int), 2, 1, 4)(3)

т.е. изначально имелось в виду
Bind!([1,0,3]).bind!(&checker!(int,int,int,int),2,1,4)(3) ?

тогда должно работать.

Иными словами не более одного списка !(...). Компилятор не ошибется 
выбирая из него аргументы слева направо по мере необходимости.

> readln();
> }


-- 
Dmitry Olshansky


More information about the Digitalmars-d-learn mailing list