public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/49637] New: template function overload incorrectly ambiguous
@ 2011-07-05  2:04 timothyjgiese at gmail dot com
  2011-07-05  2:05 ` [Bug c++/49637] " timothyjgiese at gmail dot com
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: timothyjgiese at gmail dot com @ 2011-07-05  2:04 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

           Summary: template function overload incorrectly ambiguous
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: timothyjgiese@gmail.com


Created attachment 24685
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24685
gcc -v -save-temps main.cpp [[stderr]]

The following code works fine with gcc 4.4.3 20100127 (and I'm pretty sure it
worked with 4.6.0 before I updated gcc-c++ yesterday); so maybe this is a
regression from a relatively recent change.

Here's the minimal test case:


struct S { typedef int iterator; };
template <typename T, typename U> void F( typename T::iterator, U   ) {}
template <typename T>             void F( typename T::iterator, int ) {}
int main()
{
  S::iterator i(42);
  F<S>(i,1); // FAILS=4.6.0 20110530 ; OK=4.4.3 20100127
  return 0;
}


g++ without any other options produces the following (incorrect) error:

main.cpp: In function ‘int main()’:
main.cpp:7:11: error: call of overloaded ‘F(S::iterator&, int)’ is ambiguous
main.cpp:7:11: note: candidates are:
main.cpp:2:40: note: void F(typename T::iterator, U) [with T = S, U = int,
typename T::iterator = int]
main.cpp:3:28: note: void F(typename T::iterator, int) [with T = S, typename
T::iterator = int]

Earlier version of g++ did not produce this error.

Note that if I change the definition of F to void F(T,U) and void F(T,int) and
pass in S::iterator as the template argument, then it compiles without error.  
So, it's somehow having a problem with the typename with deduction.

I'd be appreciative if someone simply confirmed if this is a bug or not.
I have a lot of code that fails now that didn't fail a few days ago, and I'm
now wondering if I need to change my code or change back to an older compiler
until this gets resolved.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
@ 2011-07-05  2:05 ` timothyjgiese at gmail dot com
  2011-07-05 12:43 ` redi at gcc dot gnu.org
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: timothyjgiese at gmail dot com @ 2011-07-05  2:05 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

--- Comment #1 from Timothy J Giese <timothyjgiese at gmail dot com> 2011-07-05 02:04:49 UTC ---
Created attachment 24686
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24686
minimal test case


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
  2011-07-05  2:05 ` [Bug c++/49637] " timothyjgiese at gmail dot com
@ 2011-07-05 12:43 ` redi at gcc dot gnu.org
  2011-07-05 15:41 ` timothyjgiese at gmail dot com
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: redi at gcc dot gnu.org @ 2011-07-05 12:43 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at gcc dot gnu.org

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-07-05 12:42:26 UTC ---
(In reply to comment #0)
> Earlier version of g++ did not produce this error.

G++ 4.5.2 does, as does Clang++. Comeau online accepts it.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
  2011-07-05  2:05 ` [Bug c++/49637] " timothyjgiese at gmail dot com
  2011-07-05 12:43 ` redi at gcc dot gnu.org
@ 2011-07-05 15:41 ` timothyjgiese at gmail dot com
  2011-07-05 16:04 ` timothyjgiese at gmail dot com
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: timothyjgiese at gmail dot com @ 2011-07-05 15:41 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

--- Comment #3 from Timothy J Giese <timothyjgiese at gmail dot com> 2011-07-05 15:40:59 UTC ---
The original minimal test case also fails to compile with g++ 4.5.1.

I can confirm that the following compiles fine with g++ 4.6.0, 4.5.1, and
4.4.3.

struct S { typedef int iterator; };
template <typename T, typename U> void F( T, U   ) {}
template <typename T>             void F( T, int ) {}
int main()
{
  S::iterator i(42);
  F< S::iterator >(i,1); // OK 4.6.0, 4.5.1, 4.4.3 
  return 0;
}

Since this works, then (IMO) the original minimal test case should work as
well.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
                   ` (2 preceding siblings ...)
  2011-07-05 15:41 ` timothyjgiese at gmail dot com
@ 2011-07-05 16:04 ` timothyjgiese at gmail dot com
  2011-07-05 16:37 ` schaub.johannes at googlemail dot com
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: timothyjgiese at gmail dot com @ 2011-07-05 16:04 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

--- Comment #4 from Timothy J Giese <timothyjgiese at gmail dot com> 2011-07-05 16:04:29 UTC ---
icpc (ICC) 11.1 20091130  compiles the original minimal test case without
warning nor error.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
                   ` (3 preceding siblings ...)
  2011-07-05 16:04 ` timothyjgiese at gmail dot com
@ 2011-07-05 16:37 ` schaub.johannes at googlemail dot com
  2011-07-05 17:29 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: schaub.johannes at googlemail dot com @ 2011-07-05 16:37 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

Johannes Schaub <schaub.johannes at googlemail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |schaub.johannes at
                   |                            |googlemail dot com

--- Comment #5 from Johannes Schaub <schaub.johannes at googlemail dot com> 2011-07-05 16:36:14 UTC ---
(In reply to comment #1)
> Created attachment 24686 [details]
> minimal test case

IMO this is ambiguous. When doing partial ordering, in both cases the 'T'
remains undeduced. Recall that partial ordering is, apart from stripping
parameters that have no corresponding argument in a function call context,
independent from the context of the ordering. So you cannot take the 'S' that
you passed explicitly into account. The spec says (FDIS, C++0x)

"In most cases, all template parameters must have values in order for deduction
to succeed, but for partial ordering purposes a template parameter may remain
without a value provided it is not used in the types being used for partial
ordering. [ Note: A template parameter used in a non-deduced context is
considered used. — end note ]"


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
                   ` (4 preceding siblings ...)
  2011-07-05 16:37 ` schaub.johannes at googlemail dot com
@ 2011-07-05 17:29 ` redi at gcc dot gnu.org
  2011-07-05 17:34 ` timothyjgiese at gmail dot com
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: redi at gcc dot gnu.org @ 2011-07-05 17:29 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

--- Comment #6 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-07-05 17:28:09 UTC ---
(In reply to comment #3)
> struct S { typedef int iterator; };
> template <typename T, typename U> void F( T, U   ) {}
> template <typename T>             void F( T, int ) {}
> int main()
> {
>   S::iterator i(42);
>   F< S::iterator >(i,1); // OK 4.6.0, 4.5.1, 4.4.3 
>   return 0;
> }
> 
> Since this works, then (IMO) the original minimal test case should work as
> well.

But that's not the same, T can be deduced here.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
                   ` (5 preceding siblings ...)
  2011-07-05 17:29 ` redi at gcc dot gnu.org
@ 2011-07-05 17:34 ` timothyjgiese at gmail dot com
  2011-07-05 18:02 ` timothyjgiese at gmail dot com
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: timothyjgiese at gmail dot com @ 2011-07-05 17:34 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

--- Comment #7 from Timothy J Giese <timothyjgiese at gmail dot com> 2011-07-05 17:34:11 UTC ---
(In reply to comment #5)
> (In reply to comment #1)
> > Created attachment 24686 [details]
> > minimal test case
> 
> IMO this is ambiguous.

> When doing partial ordering, in both cases the 'T'
> remains undeduced.

That's OK; T doesn't need to be deduced, because it is explicitly passed in.
Only the second argument needs to be deduced.

> Recall that partial ordering is, apart from stripping
> parameters that have no corresponding argument in a function call context,
> independent from the context of the ordering. So you cannot take the 'S' that
> you passed explicitly into account. The spec says (FDIS, C++0x)
> 

I interpret "partial ordering" to mean: "the process of choosing which function
to use based on which one is the most specialized".

I interpret your sentence to mean: "the process of choosing which function to
use is independent of how the function is called".  My interpretation feels
weird because it is the specific manner in which the function is called that
the partial ordering process makes its decision, no?


> "In most cases, all template parameters must have values in order for deduction
> to succeed, but for partial ordering purposes a template parameter may remain
> without a value provided it is not used in the types being used for partial
> ordering. [ Note: A template parameter used in a non-deduced context is
> considered used. — end note ]"



"A template parameter used in a non-deduced context is considered used."

To me means:
T is being used in a non-deduced context, so it is being "used"; therefore,
it's template parameter must be specified in order to achieve partial ordering.


"...for partial ordering purposes a template parameter may remain
without a value provided it is not used in the types being used for partial
ordering."

To me means:
...for partial ordering purposes [the second template argument] may remain
without a value provided it is not [the "thingie" that determines the level of
specialization.]

ACK!
So, I think my interpretation here is in agreement with your conclusion.

However, this conclusion had nothing to do with the fact that T was being used
in a non-deductible context, right?  It had to do with the second argument.

Therefore, shouldn't the small test code in Comment #3 fail?
The second template argument is left without a value, but it's value is used to
determine the level of specialization in the partial ordering process.

Or more generally: You can't overload a template function without providing all
of the template parameters, because the unspecified parameters cannot be used
to determine the partial ordering.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
                   ` (6 preceding siblings ...)
  2011-07-05 17:34 ` timothyjgiese at gmail dot com
@ 2011-07-05 18:02 ` timothyjgiese at gmail dot com
  2011-07-05 19:48 ` jason at gcc dot gnu.org
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: timothyjgiese at gmail dot com @ 2011-07-05 18:02 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

--- Comment #8 from Timothy J Giese <timothyjgiese at gmail dot com> 2011-07-05 18:02:26 UTC ---
(In reply to comment #7)
> (In reply to comment #5)
> > (In reply to comment #1)
> > > Created attachment 24686 [details]
> > > minimal test case
> > 
> > IMO this is ambiguous.
> 
> > When doing partial ordering, in both cases the 'T'
> > remains undeduced.
> 
> That's OK; T doesn't need to be deduced, because it is explicitly passed in.
> Only the second argument needs to be deduced.

OH.  I think I see what you are saying here.  I now think that you're saying
"the partial ordering will try to deduce the arguments regardless of whether or
not you tell it not to deduce it."

Damn, I wouldn't have written the C++ standard that way.

I now have to tell people to specialize versions of
template< T_iterator, T_const_iterator, T_value_type >
instead of 
template<T>
..and pray that their implementations do indeed use the right "T" for each of
the arguments.  :(


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
                   ` (7 preceding siblings ...)
  2011-07-05 18:02 ` timothyjgiese at gmail dot com
@ 2011-07-05 19:48 ` jason at gcc dot gnu.org
  2011-07-05 19:51 ` jason at gcc dot gnu.org
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: jason at gcc dot gnu.org @ 2011-07-05 19:48 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

--- Comment #9 from Jason Merrill <jason at gcc dot gnu.org> 2011-07-05 19:48:14 UTC ---
(In reply to comment #8)
> OH.  I think I see what you are saying here.  I now think that you're saying
> "the partial ordering will try to deduce the arguments regardless of whether or
> not you tell it not to deduce it."

Not exactly.  The deduction done in partial ordering is not the same as the
deduction done for the call itself; partial ordering tries to find template
arguments which will make one signature match the other.  Here, deducing U =
int makes the first signature match the second, but T is only used in
non-deduced context, so we don't have a value for it.  If typename were a
deduced context, we could deduce T = T and win.

It's not clear to me why partial ordering requires that we deduce values for
all used parameters anyway.  I'm not sure what the EDG front end is doing here,
I guess I'll raise it with the committee.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
                   ` (8 preceding siblings ...)
  2011-07-05 19:48 ` jason at gcc dot gnu.org
@ 2011-07-05 19:51 ` jason at gcc dot gnu.org
  2011-07-05 21:06 ` timothyjgiese at gmail dot com
  2011-09-26 22:47 ` jason at gcc dot gnu.org
  11 siblings, 0 replies; 13+ messages in thread
From: jason at gcc dot gnu.org @ 2011-07-05 19:51 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

--- Comment #10 from Jason Merrill <jason at gcc dot gnu.org> 2011-07-05 19:51:02 UTC ---
This is related to

http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#214


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
                   ` (9 preceding siblings ...)
  2011-07-05 19:51 ` jason at gcc dot gnu.org
@ 2011-07-05 21:06 ` timothyjgiese at gmail dot com
  2011-09-26 22:47 ` jason at gcc dot gnu.org
  11 siblings, 0 replies; 13+ messages in thread
From: timothyjgiese at gmail dot com @ 2011-07-05 21:06 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

Timothy J Giese <timothyjgiese at gmail dot com> changed:

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

--- Comment #11 from Timothy J Giese <timothyjgiese at gmail dot com> 2011-07-05 21:05:54 UTC ---
These were some useful explanations - thanks gang.

I'm going to go ahead and close this because it seems clear now that what g++
is doing is not incorrect.

To close this off, I'm going to show a work-around for the original minimal
test case, just in case someone lands here from a search engine with a similar
problem:



#include <iostream>

template <class T,class U>  struct TypeMatch      { static bool const value =
false; };
template <class T>          struct TypeMatch<T,T> { static bool const value =
true;  };

// Create 2 functions with different names
struct S { typedef int iterator; };
template <class T,class U> void FU  (typename T::iterator,U  ) { std::cout <<
"FU"   << std::endl; };
template <class T>         void Fint(typename T::iterator,int) { std::cout <<
"Fint" << std::endl; };

// Create a selector function that acts like an overload
template <class T,class U> inline void F( typename T::iterator i, U u )
{
  if ( TypeMatch<int,U>::value ) { Fint<T>(i,u); }
  else                           { FU<T,U>(i,u); };
};

// Disadvantage = every new "overload" needs to be inserted into F
// However; I won't run into this with my immediate use-case, so I'm not going
to complain too hard


int main()
{
  S::iterator i(42);
  F<S>(i,1);      // Compiles OK; prints "Fint"
  F<S>(i,true);   // Compiles OK; prints "FU"
  return 0;
};



This work-around compiles fine on g++ 4.6.0.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Bug c++/49637] template function overload incorrectly ambiguous
  2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
                   ` (10 preceding siblings ...)
  2011-07-05 21:06 ` timothyjgiese at gmail dot com
@ 2011-09-26 22:47 ` jason at gcc dot gnu.org
  11 siblings, 0 replies; 13+ messages in thread
From: jason at gcc dot gnu.org @ 2011-09-26 22:47 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49637

Jason Merrill <jason at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |SUSPENDED
   Last reconfirmed|                            |2011-09-26
         Resolution|INVALID                     |
     Ever Confirmed|0                           |1

--- Comment #12 from Jason Merrill <jason at gcc dot gnu.org> 2011-09-26 21:36:49 UTC ---
I've suggested that we reopen DR 214 in order to make this testcase valid.


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-09-26 21:37 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-05  2:04 [Bug c++/49637] New: template function overload incorrectly ambiguous timothyjgiese at gmail dot com
2011-07-05  2:05 ` [Bug c++/49637] " timothyjgiese at gmail dot com
2011-07-05 12:43 ` redi at gcc dot gnu.org
2011-07-05 15:41 ` timothyjgiese at gmail dot com
2011-07-05 16:04 ` timothyjgiese at gmail dot com
2011-07-05 16:37 ` schaub.johannes at googlemail dot com
2011-07-05 17:29 ` redi at gcc dot gnu.org
2011-07-05 17:34 ` timothyjgiese at gmail dot com
2011-07-05 18:02 ` timothyjgiese at gmail dot com
2011-07-05 19:48 ` jason at gcc dot gnu.org
2011-07-05 19:51 ` jason at gcc dot gnu.org
2011-07-05 21:06 ` timothyjgiese at gmail dot com
2011-09-26 22:47 ` jason at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).