www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - IFTI for constructors worth a DIP?

reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
I think it should be mostly stright-forward and we can get rid of 
“instantiator” functions to do IFTI.

The problem (I guess) is 2 type parameter lists, one of aggregate 
and the other of function:

struct Foo(T)
if (isSomeSuch!T)
{
     this(U)(T a, U u) if (isSomethindElse!U) {...}
     this(R)(T x, R r) if (yetAnother!U){ ... }
}

I believe in such a case compiler can as far as IFTI goes just 
consider a combined tuple of types.

Thoughts?
Mar 29 2018
parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On Friday, 30 March 2018 at 06:21:27 UTC, Dmitry Olshansky wrote:
 I think it should be mostly stright-forward and we can get rid 
 of “instantiator” functions to do IFTI.

 The problem (I guess) is 2 type parameter lists, one of 
 aggregate and the other of function:

 struct Foo(T)
 if (isSomeSuch!T)
 {
     this(U)(T a, U u) if (isSomethindElse!U) {...}
     this(R)(T x, R r) if (yetAnother!U){ ... }
 }
More interesting case... struct Foo(T) { alias K = T.K; this(K k) { .... } // same } In general it might be impossible (if we throw in more static ifs on T’s type) but well IFTI is not 100% solution anyway.
 I believe in such a case compiler can as far as IFTI goes just 
 consider a combined tuple of types.

 Thoughts?
Mar 29 2018
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 3/30/18 2:25 AM, Dmitry Olshansky wrote:
 On Friday, 30 March 2018 at 06:21:27 UTC, Dmitry Olshansky wrote:
 I think it should be mostly stright-forward and we can get rid of 
 “instantiator” functions to do IFTI.

 The problem (I guess) is 2 type parameter lists, one of aggregate and 
 the other of function:

 struct Foo(T)
 if (isSomeSuch!T)
 {
     this(U)(T a, U u) if (isSomethindElse!U) {...}
     this(R)(T x, R r) if (yetAnother!U){ ... }
 }
More interesting case... struct Foo(T) {      alias K = T.K;      this(K k) { .... }      // same } In general it might be impossible (if we throw in more static ifs on T’s type) but well IFTI is not 100% solution anyway.
 I believe in such a case compiler can as far as IFTI goes just 
 consider a combined tuple of types.

 Thoughts?
The easy way to test these is to see what IFTI does now: import std.traits; template foo(T) if (isIntegral!T) { void foo(U)(T a, U u) if (isSomeString!U) {} } void main() { foo(1, "hello"); } onlineapp.d(11): Error: template onlineapp.foo cannot deduce function from argument types !()(int, string), candidates are: onlineapp.d(3): onlineapp.foo(T) if (isIntegral!T) Your second case: struct Foo(T) { alias K = T.K; this(K k) { .... } // same } I can't see at all how this would work, as there may be infinite types for T that have an alias K that matches. However, a simpler case: template foo(T) { alias K = T; void foo(K k) {} } void main() { foo(1); } onlineapp.d(4): Error: undefined identifier K onlineapp.d(10): Error: template onlineapp.foo cannot deduce function from argument types !()(int), candidates are: onlineapp.d(1): onlineapp.foo(T)(K k) So it appears IFTI wouldn't be up to the task if there are aliases involved, or nested templates. But the simplest cases it does work with: import std.traits; template foo(T, U) if (isIntegral!T && isSomeString!U) { void foo(T a, U u) {} } void main() { foo(1, "hello"); } A class/struct ctor (where the constructor itself isn't a template) isn't any different, I can't see why it wouldn't work. -Steve
Mar 30 2018