www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1650] New: Incorrect overload selected with IFTI

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650

           Summary: Incorrect overload selected with IFTI
           Product: D
           Version: 1.023
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: sean f4.ca


Given the following code:

    void proc(T)( T val )
    {
        printf( "proc:T\n" );
    }

    void proc(T,U=void)( T[] val )
    {
        printf( "proc:T[]\n" );
    }

    void main()
    {
        proc( 0 );
        proc( "abc".dup );
    }

I would expect to see:

    proc:T
    proc:T[]

Because proc:T[] is more specialized and thus should be preferred for the
second call.  Instead, it prints:

    proc:T
    proc:T

Interestingly, moving the dummy parameter to the first function:

    void proc(T,U=void)( T val )
    {
        printf( "proc:T\n" );
    }

    void proc(T)( T[] val )
    {
        printf( "proc:T[]\n" );
    }

    void main()
    {
        proc( 0 );
        proc( "abc".dup );
    }

Results in the expected behavior:

    proc:T
    proc:T[]

I can only assume this means that the dummy parameters required to support
overloading are considered for determining how specialized a particular
function is, even though they are not used in the function parameter list.


-- 
Nov 08 2007
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650


smjg iname.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |smjg iname.com
           Keywords|                            |spec





I'm not sure what's meant to happen here.  Both templates match the argument
type, but it could be the template parameters, not the function parameters,
that somehow determine which template is the more specific match.


-- 
Nov 10 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650






The second overload is a more exact match for array parameters.  My original
bug report shows what the expected behavior is here.


-- 
Nov 11 2007
prev sibling next sibling parent reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650







 The second overload is a more exact match for array parameters. 
There's no such thing as a "more exact match" - either a match is exact or it isn't. In this case, both are exact matches.
 My original bug report shows what the expected behavior is here.
Remarks like that are no use without an indication of how you have come to that conclusion. What statement(s) in the spec are you going by, exactly? --
Nov 11 2007
parent Sean Kelly <sean f4.ca> writes:
d-bugmail puremagic.com wrote:
 http://d.puremagic.com/issues/show_bug.cgi?id=1650



 The second overload is a more exact match for array parameters. 
There's no such thing as a "more exact match" - either a match is exact or it isn't. In this case, both are exact matches.
Sorry. I meant "more specialized match." This is how C++ behaves, and I expected D to behave the same way.
 My original bug report shows what the expected behavior is here.
Remarks like that are no use without an indication of how you have come to that conclusion. What statement(s) in the spec are you going by, exactly?
None. By Walter's statement to me in the newsgroup a year or so ago that D templates would behave this way. Sean
Nov 11 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650






I don't know why the previous reply is said to have come from Sean Chittenden,
but no mater.  If it helps, I verified that this was a bug before submitting
this ticket because the book covers this topic and I wanted to be sure the
discussion was correct.  I'm adding this comment to clarify the situation
because the book is now available and a question or two has come up about the
related (currently broken) example.


-- 
Jan 15 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650






The "most specialized" template selection algorithm works with the template
parameters, not the function parameters.
Currently, the only way to make this example work is:

void proc(T, U=void)( T val )
{
    printf( "proc:T\n" );
}

void proc(T:U[], U)( T val )
{
    printf( "proc:T[]\n" );
}

void main()
{
    proc( 0 );
    proc( "abc".dup );
}

because (U[],U) is a match for (T,U), but (T,U) is not a match for (U[],U).


-- 
Jun 13 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650






So are you saying that the wrong function is selected because D doesn't have
ADL?  And can you explain why the first template is more specialized than the
other?  Is it simply because it has fewer template parameters?


-- 
Jun 14 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650






 So are you saying that the wrong function is selected because D doesn't have
ADL? No, this has nothing whatsoever to do with ADL. Template functions are overloaded based on the template parameters, not the function parameters.
And can you explain why the first template is more specialized than the
other? Specialization heirarchy is determined the same way as in C++. Template A is "at least as specialized" as template B if the template parameters of A can be used to call B. In the examples, (T) can call (T,U=void), so it is at least as specialized. But (T,void) cannot call (T), so it is equally or less specialized. Therefore (T) is more specialized. (I know this is a bit of a bear to slog through.) --
Jun 14 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650






Okay, I understand the logic, though I'm not sure I understand the reasoning
behind it.  I would expect the more correct set of function parameters to be
chosen among the set of instantiable function templates rather than the
reverse.

So it appears this all came up because we currently need to add dummy template
parameters to disambiguate between overloads--adding the dummy parameter
effectively changes the overload decisions for the set of matching functions. 
You've changed the equation a bit by making one template a specialization of
the other, so the dummy parameter U could be dropped altogether.  Given that
dummy parameters seem to alter the overloading behavior of a set of functions,
I'm hesitant to endorse it as a viable option for overloading template
functions.  Perhaps this proposed solution should be reconsidered?


-- 
Jun 15 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650






Oh, I suppose I should mention that the reason this all came up in the first
place is because specialization as in your example doesn't work if the
parameter is a static array, while my original example does.  That's what
prompted the design I'd originally chosen.


-- 
Jun 15 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650







 Okay, I understand the logic, though I'm not sure I understand the reasoning
 behind it.  I would expect the more correct set of function parameters to be
 chosen among the set of instantiable function templates rather than the
 reverse.
Let me clarify this a bit. My original (incorrect) understanding of "more specialized" related to the amount of 'work' required to make the set of function parameters work for the supplied arguments. For example: void fn(T)( T val ) {} void fn(T)( T[] val ) {} With the above, I would expect the second function to be a better match for array arguments because T represents less of the complete type, since the array specifier "[]" is explicit. Then I added the dummy template parameter so the module would compile. --
Jun 15 2008
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650


Witold Baryluk <baryluk smp.if.uj.edu.pl> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |baryluk smp.if.uj.edu.pl



21:09:31 PST ---
You should use probably something like this:
void proc(T : T[])(T[] val) {
}

Is there any reason this is still open?


I cheked documentation and there is such snippet:
  void Foo(T, U=T*)(T t) { U p; ... }

  int x;
  Foo(&x);    // T is int, U is int*

Well, for me it is strange that comment says "T is int", Foo is specialized and
recived T (int), but we give it a pointer. Something really wrong somewhere.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 24 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1650


Walter Bright <bugzilla digitalmars.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID



21:39:46 PST ---
I believe the spec and the behavior of the compiler are matching and correct.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 21 2012