www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template Parameter Deduction

reply "Paul D Anderson" <claude.reins msnmail.com> writes:
This used to work in D2.065:

given

1) public T mul(T)(in T x, in T y,
     Context context = T.context) if (isDecimal!T)
     // one template parameter for the two input values

and

2) public T mul(T, U)(in T x, U n, Context context = T.context)
     if (isDecimal!T && isIntegral!U)
     // two different template parameters for the two input values

then

3) dec9 arg1 = dec9("1.20");
    long arg2 = 3;
    result = mul(arg1, arg2);
    // correctly deduced function

But now (D2.066.1) either 1) has to be changed to

1) public T mul(T, U)(in T x, U y, Context context = T.context)
     if (isDecimal!T && isDecimal!U)
     // two identical template parameters for the two input values

or 3) has to be changed to

3) dec9 arg1 = dec9("1.20");
    long arg2 = 3;
    result = mul!(dec9,long)(arg1, arg2);
    // template parameters have to be made explicit

Is this expecded behavior?

Paul
Mar 11 2015
next sibling parent "Paul D Anderson" <claude.reins msnmail.com> writes:
On Wednesday, 11 March 2015 at 22:44:12 UTC, Paul D Anderson 
wrote:
 This used to work in D2.065:

 given

 1) public T mul(T)(in T x, in T y,
     Context context = T.context) if (isDecimal!T)
     // one template parameter for the two input values

 and

 2) public T mul(T, U)(in T x, U n, Context context = T.context)
     if (isDecimal!T && isIntegral!U)
     // two different template parameters for the two input 
 values

 then

 3) dec9 arg1 = dec9("1.20");
    long arg2 = 3;
    result = mul(arg1, arg2);
    // correctly deduced function

 But now (D2.066.1) either 1) has to be changed to

 1) public T mul(T, U)(in T x, U y, Context context = T.context)
     if (isDecimal!T && isDecimal!U)
     // two identical template parameters for the two input 
 values

 or 3) has to be changed to

 3) dec9 arg1 = dec9("1.20");
    long arg2 = 3;
    result = mul!(dec9,long)(arg1, arg2);
    // template parameters have to be made explicit

 Is this expecded behavior?

 Paul
or *expected* behavior
Mar 11 2015
prev sibling next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/11/2015 03:44 PM, Paul D Anderson wrote:
 This used to work in D2.065:

 given

 1) public T mul(T)(in T x, in T y,
      Context context = T.context) if (isDecimal!T)
      // one template parameter for the two input values

 and

 2) public T mul(T, U)(in T x, U n, Context context = T.context)
      if (isDecimal!T && isIntegral!U)
      // two different template parameters for the two input values

 then

 3) dec9 arg1 = dec9("1.20");
     long arg2 = 3;
     result = mul(arg1, arg2);
     // correctly deduced function

 But now (D2.066.1) either 1) has to be changed to

 1) public T mul(T, U)(in T x, U y, Context context = T.context)
      if (isDecimal!T && isDecimal!U)
      // two identical template parameters for the two input values

 or 3) has to be changed to

 3) dec9 arg1 = dec9("1.20");
     long arg2 = 3;
     result = mul!(dec9,long)(arg1, arg2);
     // template parameters have to be made explicit

 Is this expecded behavior?

 Paul
Hint: It makes it much simpler to work with complete code. The following code took a while for me to put together: template isDecimal(T) { enum isDecimal = true; } template isIntegral(T) { enum isIntegral = true; } public T mul(T)(in T x, in T y, Context context = T.context) if (isDecimal!T) // one template parameter for the two input values { return x; } alias Context = int; public T mul(T, U)(in T x, U n, Context context = T.context) if (isDecimal!T && isIntegral!U) // two different template parameters for the two input values { return x; } struct dec9 { string s; enum context = 42; } void main() { dec9 arg1 = dec9("1.20"); long arg2 = 3; dec9 result = mul(arg1, arg2); // correctly deduced function } Yes, it fails with 2.066.1 but compiles fine with git head. Ali
Mar 11 2015
parent "Paul D Anderson" <claude.reins msnmail.com> writes:
On Wednesday, 11 March 2015 at 23:04:15 UTC, Ali Çehreli wrote:
 On 03/11/2015 03:44 PM, Paul D Anderson wrote:
 This used to work in D2.065:

 given

 1) public T mul(T)(in T x, in T y,
     Context context = T.context) if (isDecimal!T)
     // one template parameter for the two input values

 and

 2) public T mul(T, U)(in T x, U n, Context context = T.context)
     if (isDecimal!T && isIntegral!U)
     // two different template parameters for the two input 
 values

 then

 3) dec9 arg1 = dec9("1.20");
    long arg2 = 3;
    result = mul(arg1, arg2);
    // correctly deduced function

 But now (D2.066.1) either 1) has to be changed to

 1) public T mul(T, U)(in T x, U y, Context context = T.context)
     if (isDecimal!T && isDecimal!U)
     // two identical template parameters for the two input 
 values

 or 3) has to be changed to

 3) dec9 arg1 = dec9("1.20");
    long arg2 = 3;
    result = mul!(dec9,long)(arg1, arg2);
    // template parameters have to be made explicit

 Is this expecded behavior?

 Paul
Hint: It makes it much simpler to work with complete code. The following code took a while for me to put together: template isDecimal(T) { enum isDecimal = true; } template isIntegral(T) { enum isIntegral = true; } public T mul(T)(in T x, in T y, Context context = T.context) if (isDecimal!T) // one template parameter for the two input values { return x; } alias Context = int; public T mul(T, U)(in T x, U n, Context context = T.context) if (isDecimal!T && isIntegral!U) // two different template parameters for the two input values { return x; } struct dec9 { string s; enum context = 42; } void main() { dec9 arg1 = dec9("1.20"); long arg2 = 3; dec9 result = mul(arg1, arg2); // correctly deduced function } Yes, it fails with 2.066.1 but compiles fine with git head. Ali
Thanks to you and John for taking the time to work this out. I didn't mean for anyone to rebuild the example -- I was just hoping there was a quick answer based on known language changes. I should have included complete example code. At any rate, it looks like there is a hiccup in the template parameter deduction code and that it is being fixed. And it's easy to work around. I'll dig a little deeper to see if I can find a related bug report. Paul
Mar 12 2015
prev sibling parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Wednesday, 11 March 2015 at 22:44:12 UTC, Paul D Anderson 
wrote:
 This used to work in D2.065:

 given

 1) public T mul(T)(in T x, in T y,
     Context context = T.context) if (isDecimal!T)
     // one template parameter for the two input values

 and

 2) public T mul(T, U)(in T x, U n, Context context = T.context)
     if (isDecimal!T && isIntegral!U)
     // two different template parameters for the two input 
 values

 then

 3) dec9 arg1 = dec9("1.20");
    long arg2 = 3;
    result = mul(arg1, arg2);
    // correctly deduced function

 But now (D2.066.1) either 1) has to be changed to

 1) public T mul(T, U)(in T x, U y, Context context = T.context)
     if (isDecimal!T && isDecimal!U)
     // two identical template parameters for the two input 
 values

 or 3) has to be changed to

 3) dec9 arg1 = dec9("1.20");
    long arg2 = 3;
    result = mul!(dec9,long)(arg1, arg2);
    // template parameters have to be made explicit

 Is this expecded behavior?

 Paul
This works with 2.066.1 and git HEAD import std.stdio; void mul(T)(in T x, in T y, long i = T.init) if (is(T == int)) { writeln("same"); } void mul(T, U)(in T x, U n, long i = T.init) if (is(T == int) && is(U == ulong)) { writeln("different"); } void main() { mul(1,2); mul(1,2UL); } Perhaps there is something important in your incomplete example that I have missed out.
Mar 11 2015