digitalmars.D.learn - Template Parameter Deduction
- Paul D Anderson (25/25) Mar 11 2015 This used to work in D2.065:
- Paul D Anderson (3/30) Mar 11 2015 or *expected* behavior
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (38/63) Mar 11 2015 Hint: It makes it much simpler to work with complete code. The following...
- Paul D Anderson (10/88) Mar 12 2015 Thanks to you and John for taking the time to work this out. I
- John Colvin (21/48) Mar 11 2015 This works with 2.066.1 and git HEAD
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
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
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
On Wednesday, 11 March 2015 at 23:04:15 UTC, Ali Çehreli wrote:On 03/11/2015 03:44 PM, Paul D Anderson wrote: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. PaulThis 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? PaulHint: 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 12 2015
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









"Paul D Anderson" <claude.reins msnmail.com> 