Title
Partial ordering and non-deduced arguments
Status
nad
Section
12.2.4 [over.match.best]
Submitter
Rani Sharoni

Created on 2004-01-19.00:00:00 last changed 24 months ago

Messages

Date: 2022-11-20.07:54:16

CWG 2022-11-11

The second function parameter contains template parameters not deducible in its context, thus that parameter does not contribute to partial ordering. There is no implementation divergence. Close as NAD.

Date: 2004-10-15.00:00:00

Notes from October 2004 meeting:

John Spicer will investigate further to see if any action is required.

(See also issue 885.)

Date: 2004-01-19.00:00:00

It's not clear how overloading and partial ordering handle non-deduced pairs of corresponding arguments. For example:

template<typename T>
struct A { typedef char* type; };

template<typename T> char* f1(T, typename A<T>::type);  // #1
template<typename T> long* f1(T*, typename A<T>::type*); // #2

long* p1 = f1(p1, 0); // #3

I thought that #3 is ambiguous but different compilers disagree on that. Comeau C/C++ 4.3.3 (EDG 3.0.3) accepted the code, GCC 3.2 and BCC 5.5 selected #1 while VC7.1+ yields ambiguity.

I intuitively thought that the second pair should prevent overloading from triggering partial ordering since both arguments are non-deduced and has different types - (char*, char**). Just like in the following:

template<typename T> char* f2(T, char*);   // #3
template<typename T> long* f2(T*, char**); // #4

long* p2 = f2(p2, 0); // #5

In this case all the compilers I checked found #5 to be ambiguous. The standard and DR 214 is not clear about how partial ordering handle such cases.

I think that overloading should not trigger partial ordering (in step 12.2.4 [over.match.best]/1/5) if some candidates have non-deduced pairs with different (specialized) types. In this stage the arguments are already adjusted so no need to mention it (i.e. array to pointer). In case that one of the arguments is non-deuced then partial ordering should only consider the type from the specialization:

template<typename T> struct B { typedef T type; };

template<typename T> char* f3(T, T);                   // #7
template<typename T> long* f3(T, typename B<T>::type); // #8

char* p3 = f3(p3, p3); // #9

According to my reasoning #9 should yield ambiguity since second pair is (T, long*). The second type (i.e. long*) was taken from the specialization candidate of #8. EDG and GCC accepted the code. VC and BCC found an ambiguity.

John Spicer: There may (or may not) be an issue concerning whether nondeduced contexts are handled properly in the partial ordering rules. In general, I think nondeduced contexts work, but we should walk through some examples to make sure we think they work properly.

Rani's description of the problem suggests that he believes that partial ordering is done on the specialized types. This is not correct. Partial ordering is done on the templates themselves, independent of type information from the specialization.

History
Date User Action Args
2022-11-20 07:54:16adminsetmessages: + msg7056
2022-11-20 07:54:16adminsetstatus: open -> nad
2022-02-18 07:47:23adminsetstatus: drafting -> open
2011-09-06 00:00:00adminsetstatus: open -> drafting
2004-11-07 00:00:00adminsetmessages: + msg1089
2004-01-19 00:00:00admincreate