digitalmars.D.learn - problem with template arguments deduction
- Zhenya (43/43) May 30 2012 Some time ago I decided to write in D something like boost ::
- Philippe Sigaud (49/49) May 30 2012 I don't see anything wrong per se. It's mainly that the compiler type
- Zhenya (2/55) May 30 2012 Thank you very much:)
- Zhenya (12/12) May 30 2012 And, one more thing
- Philippe Sigaud (2/14) May 31 2012 I'm not sure I understand the question?
- Dmitry Olshansky (6/18) May 31 2012 If you happen to be Russian, feel free to include Russian as well. I
- Zhenya (19/19) Jun 01 2012 Вот у нас есть такая конструкция
- Zhenya (19/19) Jun 01 2012 Вот у нас есть такая конструкция
- Zhenya (1/1) Jun 01 2012 Простите меня за мой английский)
- Dmitry Olshansky (25/51) Jun 01 2012 In other words:
- Zhenya (98/98) Jun 01 2012 Но тогда почему при замене Bind -> bind
- Dmitry Olshansky (10/106) Jun 01 2012 Может все-таки
- Zhenya (6/122) Jun 01 2012 В том-то и дело,что
- Dmitry Olshansky (4/128) Jun 01 2012 Лог ошибок в студию.
- Zhenya (13/13) Jun 01 2012 Error 3 Error: function expected before (), not
- Dmitry Olshansky (21/32) Jun 01 2012 It may have some problem with matching this delegate hmmm.
- Zhenya (6/45) Jun 01 2012 Error 1 basic type expected, not
- Dmitry Olshansky (9/57) Jun 01 2012 ну как же map, filter и тд работают )
- Zhenya (2/7) Jun 01 2012 нууу так не прикольно.
- Dmitry Olshansky (7/12) Jun 01 2012 Ну их много, заполни репорт в
- Zhenya (40/47) Jun 01 2012 кстати если я заменяю
- Zhenya (2/2) Jun 02 2012 Дмитрий,не подскажите как я бы мог
- Dmitry Olshansky (42/43) Jun 02 2012 Как я и говорил отписать что это баг. Да...
- Zhenya (1/1) Jun 02 2012 Куда отписать-то?)
- Dmitry Olshansky (4/5) Jun 02 2012 http://d.puremagic.com/issues/
- Zhenya (98/98) Jun 01 2012 Да,на всякий случай,текущий
Some time ago I decided to write in D something like boost :: bind.But I encountered a problem that the compiler can not deduce the template function. Here are a significant part of the code: template Combination(alias indeces,U...) { // static if(is(typeof(indeces) : uint[])) // { static if(indeces.length > 1) alias TypeTuple!(U[indeces[0]],Combination!(indeces[1..$],U)) Combination; else static if(indeces.length == 1) alias U[indeces[0]] Combination; // } } template bind(alias indeces) { // static if(is(typeof(indeces) : uint[])) // { auto bind(R,U...)(R delegate(U) dg,Combination!(indeces,U) values) { /* static if(indeces.length > 1) return bind!(update!(indeces,indeces[0]))(Curry!(indeces[0])(dg,values[0]),values[1..$]); else static if(indeces.length == 1) return Curry!(indeces[0])(dg,values[0]); */ } // } } void main() { void xyz(int x,int y,int z) { writeln("x = ",x," y = ",y," z = ",z); } // auto g = Curry!1(&xyz,cast(int)(1.1)); // g(2,3); alias Combination!([0,1],int,int,int) Arg; Arg a; bind!([0,1])(&xyz,a); readln(); } Please, explain to me what is wrong with this code
May 30 2012
I don't see anything wrong per se. It's mainly that the compiler type extraction/deduction is not powerful enough to extract U in your case. You can help it a bit by using std.traits.ParameterTypeTuple: module test; import std.stdio; import std.traits; import std.typetuple; template Combination(alias indices,U...) { static if(is(typeof(indices) : int[])) { static if(indices.length > 1) alias TypeTuple!(U[indices[0]],Combination!(indices[1..$],U)) Combination; else static if(indices.length == 1) alias U[indices[0]] Combination; } } template bind(alias indices) { static if(is(typeof(indices) : int[])) { auto bind(D,V...)(D dg, V values) if (is (D d == R delegate(U), R, U...) && is(V == Combination!(indices, ParameterTypeTuple!D))) { /* static if(indices.length > 1) return bind!(update!(indices,indices[0]))(Curry!(indices[0])(dg,values[0]),values[1..$]); else static if(indices.length == 1) return Curry!(indices[0])(dg,values[0]); */ } } } void main() { void xyz(int x,int y,int z) { writeln("x = ",x," y = ",y," z = ",z); } // auto g = Curry!1(&xyz,cast(int)(1.1)); // g(2,3); alias Combination!([0,1],int,int,int) Arg; Arg a; writeln(Arg.stringof); bind!([0,1])(&xyz,a); //readln(); }
May 30 2012
On Wednesday, 30 May 2012 at 22:19:53 UTC, Philippe Sigaud wrote:I don't see anything wrong per se. It's mainly that the compiler type extraction/deduction is not powerful enough to extract U in your case. You can help it a bit by using std.traits.ParameterTypeTuple: module test; import std.stdio; import std.traits; import std.typetuple; template Combination(alias indices,U...) { static if(is(typeof(indices) : int[])) { static if(indices.length > 1) alias TypeTuple!(U[indices[0]],Combination!(indices[1..$],U)) Combination; else static if(indices.length == 1) alias U[indices[0]] Combination; } } template bind(alias indices) { static if(is(typeof(indices) : int[])) { auto bind(D,V...)(D dg, V values) if (is (D d == R delegate(U), R, U...) && is(V == Combination!(indices, ParameterTypeTuple!D))) { /* static if(indices.length > 1) return bind!(update!(indices,indices[0]))(Curry!(indices[0])(dg,values[0]),values[1..$]); else static if(indices.length == 1) return Curry!(indices[0])(dg,values[0]); */ } } } void main() { void xyz(int x,int y,int z) { writeln("x = ",x," y = ",y," z = ",z); } // auto g = Curry!1(&xyz,cast(int)(1.1)); // g(2,3); alias Combination!([0,1],int,int,int) Arg; Arg a; writeln(Arg.stringof); bind!([0,1])(&xyz,a); //readln(); }Thank you very much:)
May 30 2012
And, one more thing if we have the following code: template foo (T) { auto foo (U) (U arg) { } } ... foo!(int)('!'); determine whether the compiler that this specialization is to an external template?
May 30 2012
On Thu, May 31, 2012 at 8:31 AM, Zhenya <zheny list.ru> wrote:And, one more thing if we have the following code: template foo (T) { =C2=A0 =C2=A0 =C2=A0 =C2=A0auto foo (U) (U arg) =C2=A0 =C2=A0 =C2=A0 =C2=A0{ =C2=A0 =C2=A0 =C2=A0 =C2=A0} } ... foo!(int)('!'); determine whether the compiler that this specialization is to an external template?I'm not sure I understand the question?
May 31 2012
On 31.05.2012 10:31, Zhenya wrote:And, one more thing if we have the following code: template foo (T) { auto foo (U) (U arg) { } } ... foo!(int)('!'); determine whether the compiler that this specialization is to an external template?If you happen to be Russian, feel free to include Russian as well. I might help translate it ;) As is your question is ... hardly understandable. -- Dmitry Olshansky
May 31 2012
Вот у нас есть такая конструкция template foo(T) { foo(U)() { } } Могут ли у компилятора при инстанциировании возникнуть трудности с пониманием какие аргументы к какому шаблону относятся? Вопрос у меня возник из-за того,что когда я применил совет Philippe Sigaud к своему полному коду компилятор не захотел его компилировать.Но когда я поменял имя внутреннего шаблона все стало хорошо.Это ведь неправильно?
Jun 01 2012
Вот у нас есть такая конструкция template foo(T) { foo(U)() { } } Могут ли у компилятора при инстанциировании возникнуть трудности с пониманием какие аргументы к какому шаблону относятся? Вопрос у меня возник из-за того,что когда я применил совет Philippe Sigaud к своему полному коду компилятор не захотел его компилировать.Но когда я поменял имя внутреннего шаблона все стало хорошо.Это ведь неправильно?
Jun 01 2012
On Friday, 1 June 2012 at 08:08:19 UTC, Zhenya wrote:Вот у нас есть такая конструкция template foo(T) { foo(U)() { } } Могут ли у компилятора при инстанциировании возникнуть трудности с пониманием какие аргументы к какому шаблону относятся? Вопрос у меня возник из-за того,что когда я применил совет Philippe Sigaud к своему полному коду компилятор не захотел его компилировать.Но когда я поменял имя внутреннего шаблона все стало хорошо.Это ведь неправильно?In other words: Given this construct:template foo(T) { foo(U)() { } }Could there be some problems with compiler not understanding which template argument goes to which template here? The question was born when I started applying Philippe Siguad's advice to my full source code compiler rejected it. But when I change inner tmeplate name it worked - it's no good, is it? Вопрос довольно сложный. Краткий ответ - нет, все идет слева направо, сверху вниз. Есть впрочем одно но - компилятор начинает выводить типы из аргументов только для последнего foo (т.е. U). То есть T в это случае дается сверху (тобой через foo!T(...) ). Впрочем в твоем примере foo не моежт вывести U из аргументов (их нет). Difficult Q. In short - no, it's all left-to-right up-to-bottom. However compiler may deduce types only for lowest foo (i.e. U). T in this case have to provided from above (by you as in foo!T(...)). --- It's me, just trying out web interface.
Jun 01 2012
Но тогда почему при замене 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); readln(); }
Jun 01 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
Jun 01 2012
On Friday, 1 June 2012 at 11:23:48 UTC, Dmitry Olshansky wrote:On 01.06.2012 15:16, Zhenya wrote:В том-то и дело,что (&checker!(int,int,int,int),2,1,4) - аргументы времени выполнения.Значит: bind!([1,0,3])(&checker!(int,int,int,int),2,1,4)(3) но не хочет компилится(Но тогда почему при замене 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(); }
Jun 01 2012
On 01.06.2012 15:40, Zhenya wrote:On Friday, 1 June 2012 at 11:23:48 UTC, Dmitry Olshansky wrote:Лог ошибок в студию. -- Dmitry OlshanskyOn 01.06.2012 15:16, Zhenya wrote:В том-то и дело,что (&checker!(int,int,int,int),2,1,4) - аргументы времени выполнения.Значит: bind!([1,0,3])(&checker!(int,int,int,int),2,1,4)(3) но не хочет компилится(Но тогда почему при замене 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(); }
Jun 01 2012
Error 3 Error: function expected before (), not bind(&checker,2,1,4) of type _error_ c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98 Error 1 Error: template instance bind!([0,2]) bind!([0,2]) does not match template declaration bind(D,V...) c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 81 Error 2 Error: template instance main.bind!([1,0,3]).bind!(void delegate(int _param_0, int _param_1, int _param_2, int _param_3) system,int,int,int) error instantiating c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98
Jun 01 2012
On 01.06.2012 15:47, Zhenya wrote:Error 3 Error: function expected before (), not bind(&checker,2,1,4) of type _error_ c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98 Error 1 Error: template instance bind!([0,2]) bind!([0,2]) does not match template declaration bind(D,V...) c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 81 Error 2 Error: template instance main.bind!([1,0,3]).bind!(void delegate(int _param_0, int _param_1, int _param_2, int _param_3) system,int,int,int) error instantiating c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98It may have some problem with matching this delegate hmmm. What if you try this: template Bind(alias indeces) if(is(typeof(indeces) : int[])) { auto bind(V...)(alias dg,V values) if(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 assert(0); } } alias instead of delegate - it's just more powerful I relaxed constraints and static ifs ---> proper template constraints. -- Dmitry Olshansky
Jun 01 2012
On Friday, 1 June 2012 at 12:38:11 UTC, Dmitry Olshansky wrote:On 01.06.2012 15:47, Zhenya wrote:Error 1 basic type expected, not alias c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 75 Похоже что alias не может быть аргументом времени выполненияError 3 Error: function expected before (), not bind(&checker,2,1,4) of type _error_ c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98 Error 1 Error: template instance bind!([0,2]) bind!([0,2]) does not match template declaration bind(D,V...) c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 81 Error 2 Error: template instance main.bind!([1,0,3]).bind!(void delegate(int _param_0, int _param_1, int _param_2, int _param_3) system,int,int,int) error instantiating c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98It may have some problem with matching this delegate hmmm. What if you try this: template Bind(alias indeces) if(is(typeof(indeces) : int[])) { auto bind(V...)(alias dg,V values) if(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 assert(0); } } alias instead of delegate - it's just more powerful I relaxed constraints and static ifs ---> proper template constraints.
Jun 01 2012
On 01.06.2012 16:47, Zhenya wrote:On Friday, 1 June 2012 at 12:38:11 UTC, Dmitry Olshansky wrote:ну как же map, filter и тд работают ) ну передавай свой delegate как параметр времени компиляции через !(...) все будет ок ... auto bind(alias dg, V...)(V values)On 01.06.2012 15:47, Zhenya wrote:Error 1 basic type expected, not alias c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 75 Похоже что alias не может быть аргументом времени выполненияError 3 Error: function expected before (), not bind(&checker,2,1,4) of type _error_ c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98 Error 1 Error: template instance bind!([0,2]) bind!([0,2]) does not match template declaration bind(D,V...) c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 81 Error 2 Error: template instance main.bind!([1,0,3]).bind!(void delegate(int _param_0, int _param_1, int _param_2, int _param_3) system,int,int,int) error instantiating c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98It may have some problem with matching this delegate hmmm. What if you try this: template Bind(alias indeces) if(is(typeof(indeces) : int[])) { auto bind(alias dg, V...)(V values) if(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 assert(0); } } alias instead of delegate - it's just more powerful I relaxed constraints and static ifs ---> proper template constraints.Bind!(update!(indeces,indeces[0])[1..$]).bind!(Curry! (indeces[0]) (values[0]),values[1..$]);if(is(V == Combination!(indeces,ParameterTypeTuple!D))) { static if(indeces.length > 1) return-- Dmitry Olshanskyelse assert(0); } }
Jun 01 2012
ну как же map, filter и тд работают ) ну передавай свой delegate как параметр времени компиляции через !(...) все будет ок ...нууу так не прикольно. А это часом не бага у DMD?
Jun 01 2012
On 01.06.2012 16:53, Zhenya wrote:beats me.ну как же map, filter и тд работают ) ну передавай свой delegate как параметр времени компиляции через !(...) все будет ок ...нууу так не прикольно.А это часом не бага у DMD?Ну их много, заполни репорт в http://d.puremagic.com/issues/ через пару дней Кенжи Хара пофиксит если это баг ) -- Dmitry Olshansky
Jun 01 2012
On Friday, 1 June 2012 at 12:53:16 UTC, Zhenya wrote:кстати если я заменяю 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]); } } } } на class Bind(alias indeces) { static auto opCall(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..$])(Curry!(indeces[0])(dg,values[0]),values[1..$]); else return Curry!(indeces[0])(dg,values[0]); } } } то вот так Bind!([1,0,3])(&checker!(int,int,int,int),2,1,4)(3); вполне спокойно работает в чем же разница?ну как же map, filter и тд работают ) ну передавай свой delegate как параметр времени компиляции через !(...) все будет ок ...нууу так не прикольно. А это часом не бага у DMD?
Jun 01 2012
Дмитрий,не подскажите как я бы мог проверить не баг ли это?
Jun 02 2012
On 02.06.2012 11:23, Zhenya wrote:Дмитрий,не подскажите как я бы мог проверить не баг ли это?Как я и говорил отписать что это баг. Дальше это дело экспертов по компилятору ) Вот например последние что ты отипсывал, вполне катит для bug-репорта: (только сократи лишний "внешний" код) this doesn't work: 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]); } } } } while this works : class Bind(alias indeces) { static auto opCall(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..$])(Curry!(indeces[0])(dg,values[0]),values[1..$]); else return Curry!(indeces[0])(dg,values[0]); } } } -- Dmitry Olshansky
Jun 02 2012
On 02.06.2012 11:30, Zhenya wrote:Куда отписать-то?)http://d.puremagic.com/issues/ -- Dmitry Olshansky
Jun 02 2012
Да,на всякий случай,текущий исходник,который не компилится 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])(&checker!(int,int,int,int),2,1,4)(3); readln(); }
Jun 01 2012