Why is template overload a better match than a simple conversion? - c++

#include <iostream>
using namespace std;
template<typename T>
void func(T t) { std::cout << "matched template\n"; }
void func(long x) { std::cout << "matched long\n"; }
int main()
{
func(0);
}
output:
matched template
In other cases, the non-template function is preferred when overload resolution might be ambiguous, why is this one different?

§13.3.3 [over.match.best]/p1-2:
1 Define ICSi(F) as follows:
(1.1) [inapplicable bullet omitted]
(1.2) let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the type of the i-th parameter of
viable function F. 13.3.3.1 defines the implicit conversion
sequences and 13.3.3.2 defines what it means for one implicit
conversion sequence to be a better conversion sequence or worse
conversion sequence than another.
Given these definitions, a viable function F1 is defined to be a
better function than another viable function F2 if for all arguments
i, ICSi(F1) is not a worse conversion sequence than ICSi(F2),
and then
(1.3) for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
[several inapplicable bullets omitted]
(1.6) F1 is not a function template specialization and F2 is a function template specialization, or, if not that,
[inapplicable bullet omitted]
2 If there is exactly one viable function that is a better function
than all other viable functions, then it is the one selected by
overload resolution; otherwise the call is ill-formed.
§13.3.3.2 [over.ics.rank], bullet 3.2:
(3.2) Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if
(3.2.1) S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by 13.3.3.1.1, excluding any
Lvalue Transformation; the identity conversion sequence is considered
to be a subsequence of any non-identity conversion sequence)
Let F1 = func<int>(int), F2 = func(long), there's only one argument, of type int. So ICS1(F1) is the identity conversion; ICS1(F2) is an integer conversion from int to long; therefore ICS1(F1) is a better conversion sequence than ICS1(F2) per [over.ics.rank]/3.2.1 (and so by definition is not worse than ICS1(F2)). Thus per bullet 1.3 in [over.match.best], F1 is better than F2. The template/non-template tiebreaker, in bullet 1.6, simply never comes into play.

Implicit conversions may carry an overhead and may be unexpected to the programmer, so it seems logical to me that the standard selects the option which does not involve a conversion.

I think (but am not absolutely sure, i.e. don't know the exact quote from the standard, although will try to find) that if the argument does not match exactly the type of the non-template, then the template will kick in. Or, in other words, the number of conversions tends to be minimized. E.g., in
f(long)
vs
template <typename T>
f(T)
f(long) needs a conversion (from 0, e.g.int, to long), whereas no conversion is needed (of course) for the template.
After some digging and help from #T.C., the relevant part of the standard is Sec. 13.3.3, [over.match.best]. This is quite a long technical section, but basically says that the function with the Identity conversion is preferred over non-Identity conversions.

Related

Overload resolution for non-member functions (/non-constructor contexts) with std::initializer_list argument(s)

(All ISO Standard references below refer to N4659: March 2017 post-Kona working draft/C++17 DIS, and all example program results are consistent over GCC and Clang for C++11, C++14 and C++17)
Consider the following example:
#include <initializer_list>
// Denote as A.
void f(float) {}
// Denote as B.
void f(std::initializer_list<int>) {}
int main() {
// Denote call as C1.
f(1.5F); // Overload resolution picks A (trivial).
// Denote call as C2.
f({1.5F}); // Overload resolution picks B (and subsequently fails; narrowing).
return 0;
}
which results in the call C2 picking overload B as best viable function, followed by a failure due to narrowing in list initialization (governed by [dcl.init.list]/7):
error: type 'float' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
Question
Why does the f({1.5F}); function call find void f(std::initializer_list<int>) to be the unique best viable function, ranked as a better match than void f(float)? Afaics this conflicts with [over.ics.list]/4 and [over.ics.list]/9 (see details below).
I'm looking for references to the relevant standard passages.
Note that I am aware of the special rules regarding overload resolution for list initialization (constructor overloading) and std::initializer_list<> (and the various SO questions on this topic), where std::initializer_list<> is strongly preferred, as governed by [over.match.list]/1. However, afaics, this does not apply here (or, if I'm wrong, at the very least arguably conflicts with the standard examples shown in [over.ics.list]/4).
Details and investigation of my own
For both C1 and C2 calls above, overload resolution is applied as specified in [over.call.func] (as per [over.match]/2.1 and [over.match.call]/1), particularly [over.call.func]/3, and the set of candidate functions for both calls is:
candidate_functions(C1) = { void f(float),
void f(std::initializer_list<int>) }
candidate_functions(C2) = { void f(float),
void f(std::initializer_list<int>) }
and the argument list in each call is the same as the expression-list in the call.
As per [over.match.viable]/2 and [over.match.viable]/3, the set of viable functions is the same as the candidate functions for both calls:
viable_functions(C1) = { void f(float),
void f(std::initializer_list<int>) }
viable_functions(C2) = { void f(float),
void f(std::initializer_list<int>) }
Best viable functions
As per [over.match.best]/1, in short terms, the best viable function for a given function call, here specifically a single-argument call (with no special cases for the viable functions of each call), is the viable function that, for the single argument, has the best implicit conversion sequence from the single argument to the single parameter of the respective viable function.
C1: Best viable function
The call f(1.5F) has an identity standard conversion (no conversion) and thus an exact match for A (as per [over.ics.scs]/3) and A can be (trivially and) non-ambiguously chosen as the best viable function.
best_viable_function(C1) = void f(float)
C2: Best viable function
Afaics, ranking the implicit conversion sequences of the call f({1.5F}) towards viable candidates is governed by [over.ics.list], as per [over.ics.list]/1:
When an argument is an initializer list ([dcl.init.list]), it is not an expression and special rules apply for converting it to a parameter type.
Matching C2 towards A
For matching towards A where the single parameter is of the fundamental float type, [over.ics.list]/9 and particularly [over.ics.list]/9.1 applies [emphasis mine]:
Otherwise, if the parameter type is not a class:
(9.1) if the initializer list has one element that is not itself an initializer list, the implicit conversion sequence is the
one required to convert the element to the parameter type;
[ Example:
void f(int);
f( {'a'} ); // OK: same conversion as char to int
f( {1.0} ); // error: narrowing
— end example ]
[...]
This arguably means that the implicit conversion sequence for matching the call f({1.5F}} to f(float) is the same conversion sequence as float to float; i.e., identity conversion and subsequently an exact match. However, as per the example above, there must be some flaw in my logic here as the call C2 doesn't even result in an ambiguous best viable function.
Matching C2 towards B
For matching towards B where the single parameter [over.ics.list]/4 applies [emphasis mine]:
Otherwise, if the parameter type is std​::​initializer_­list<X> and
all the elements of the initializer list can be implicitly converted
to X, the implicit conversion sequence is the worst conversion
necessary to convert an element of the list to X, or if the
initializer list has no elements, the identity conversion. This
conversion can be a user-defined conversion even in the context of a
call to an initializer-list constructor. [ Example:
void f(std::initializer_list<int>);
f( {} ); // OK: f(initializer_­list<int>) identity conversion
f( {1,2,3} ); // OK: f(initializer_­list<int>) identity conversion
f( {'a','b'} ); // OK: f(initializer_­list<int>) integral promotion
f( {1.0} ); // error: narrowing
[...]
— end example ]
In this example, the implicit conversion sequence is thus the worst conversion necessary to convert the single float element of the list to int, which is a conversion ranked standard conversion sequence ([over.ics.scs]/3), particularly a narrowing conversion as per [conv.fpint]/1.
Best viable function
According to my own interpretation of the standard passages as per above, the best viable function should be the same as for the C1 call,
best_viable_function(C2) = void f(float) ?
but I'm obviously missing something.
List-initialization sequences: special case ranking when one sequence converts to std::initializer_list
[over.ics.rank]/3.1 applies for this case, and takes precedence over the other rules of [over.ics.rank]/3 [emphasis mine]:
List-initialization sequence L1 is a better conversion sequence than
list-initialization sequence L2 if
(3.1.1) L1 converts to std​::​initializer_­list<X> for some X and L2 does not, or, if not that
(3.1.2) [...]
even if one of the other rules in this paragraph would otherwise apply. [ Example:
void f1(int); // #1
void f1(std::initializer_list<long>); // #2
void g1() { f1({42}); } // chooses #2
void f2(std::pair<const char*, const char*>); // #3
void f2(std::initializer_list<std::string>); // #4
void g2() { f2({"foo","bar"}); } // chooses #4
 — end example ]
meaning that [over.ics.rank]/3.2 and [over.ics.rank]/3.3, covering distinguishing implicit conversion sequences by means of standard conversion sequences and user defined conversion sequences, respectively, does not apply, which in turn means [over.ics.list]/4 and [over.ics.list]/9 will not be used to rank the implicit conversion sequences when comparing the best match out of "C2 calls A" vs "C2 calls B".
This very topic was a defect in C++11 and C++14
It's not surprising that these conversions may come as counter-intuitive, and that the rules governing them are complicated. In the original C++11 and C++14 ISO standard releases, the call f({1.5F}); actually had ambiguous ranking rules w.r.t. the best viable function, which was covered in CWG Defect Report 1589 [emphasis mine]:
1589. Ambiguous ranking of list-initialization sequences
Section: 16.3.3.2 [over.ics.rank]
Status: CD4
Submitter: Johannes Schaub
Date: 2012-11-21
[Moved to DR at the November, 2014 meeting.]
The interpretation of the following example is unclear in the current
wording:
void f(long);
void f(initializer_list<int>);
int main() { f({1L});
The problem is that a list-initialization sequence can also be a
standard conversion sequence, depending on the types of the elements
and the type of the parameter, so more than one bullet in the list
in 16.3.3.2 [over.ics.rank] paragraph 3 applies:
[...]
These bullets give opposite results for the example above, and there
is implementation variance in which is selected.
[...]
Proposed resolution (June, 2014):
This issue is resolved by the resolution of issue
1467.
CWG Defect Report 1467 finally resolved also DR 1589, particularly adding the relevant part quoted from [over.ics.rank]/3 above [emphasis mine]:
1467. List-initialization of aggregate from same-type object
[...]
Proposed resolution (June, 2014):
[...]
Move the final bullet of 16.3.3.2 [over.ics.rank] paragraph 3 to the beginning of the list and change it as follows:
[...]
even if one of the other rules in this paragraph would otherwise apply. [Example: ... — end example]
This resolution also resolves issues 1490, 1589, 1631, 1756, and 1758.
Compilers such as GCC and Clang has since back-ported DR 1467 to earlier standards (C++11 and C++14).

Why no ambiguity in this function call?

I'm wondering why there's no ambiguity in this function call:
#include <iostream>
#include <vector>
template <class T>
class C
{
public:
typedef char c;
typedef double d;
int fun() {}
static c testFun( decltype(&C::fun) ) {return c();}
static d testFun(...) { return d(); }
};
int main() {
C<int>::testFun(0); // Why no ambiguity?
}
http://coliru.stacked-crooked.com/a/241ce5ab82b4a018
There's a ranking of implicit conversion sequences, as defined in [over.ics.rank], emphasis mine:
When comparing the basic forms of implicit conversion sequences...
- a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion
sequence or an ellipsis conversion sequence, and
- a user-defined conversion sequence (13.3.3.1.2) is a better conversion sequence than an ellipsis conversion
sequence (13.3.3.1.3).
So we have two functions:
static char testFun( int (C::*)() ) { return char(); }
static double testFun( ... ) { return double(); }
Both functions are viable for testFun(0). The first would involve a "null member pointer conversion" as per [conv.mem], and is a standard conversion sequence. The second would match the ellipsis and be an ellipsis conversion sequence. By [over.ics.rank], the former is preferred. There's no ambiguity, the one is strictly better than the other.
An ambiguous overload would arise if we had two equivalent conversion sequences that the compiler could not decide between. Consider if we had something like:
static char testFun(int* ) { return 0; }
static int testFun(char* ) { return 0; }
testFun(0);
Now both overloads would be equivalent as far as the conversion sequences go, so we'd have two viable candidates.
You have a standard conversion vs an ellipsis conversion. The standard says that a standard conversion is a better conversion sequence than the latter. [over.ics.rank]/p2:
a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion
sequence or an ellipsis conversion sequence
A pointer-to-member conversion is a standard conversion sequence. 0 is a null pointer constant and can be converted to a pointer-to-member. [conv.mem]/p1:
A null pointer constant (4.10) can be converted to a pointer to member type; the result is the null member
pointer value of that type and is distinguishable from any pointer to member not created from a null pointer
constant. Such a conversion is called a null member pointer conversion.
Therefore the first overload is preferred.
13.3.2 Viable functions
A candidate function having fewer than m parameters is viable only if it has an ellipsis in its parameter list (8.3.5). For the purposes of overload resolution, any argument for which there is no corresponding parameter is considered to “match the ellipsis” (13.3.3.1.3).
And also
Viable functions
Given the set of candidate functions, constructed as described above, the next step of overload resolution is examining arguments and parameters to reduce the set to the set of viable functions
To be included in the set of viable functions, the candidate function must satisfy the following:
1) If there are M arguments, the candidate function that has exactly M parameters is viable
2) If the candidate function has less than M parameters, but has an ellipsis parameter, it is viable.
[...]
Overloading resolution
A null pointer literal 0 should be an exact match to a function accepting a function pointer and treated as stronger than matching anything (...).

In overload resolution, does selection of a function that uses the ambiguous conversion sequence necessarily result in the call being ill-formed?

The question arose while I was researching the answer to this SO question. Consider the following code:
struct A{
operator char() const{ return 'a'; }
operator int() const{ return 10; }
};
struct B {
void operator<< (int) { }
};
int main()
{
A a;
B b;
b << a;
}
The conversion of a to int can be either via a.operator char() followed by an integral promotion, or a.operator int() followed by an identity conversion (i.e., no conversion at all). The standard says that (§13.3.3.1 [over.best.ics]/p10, footnote omitted, bolding mine; all quotes are from N3936):
If several different sequences of conversions exist that each convert
the argument to the parameter type, the implicit conversion sequence
associated with the parameter is defined to be the unique conversion
sequence designated the ambiguous conversion sequence. For the
purpose of ranking implicit conversion sequences as described in
13.3.3.2, the ambiguous conversion sequence is treated as a user-defined sequence that is indistinguishable from any other
user-defined conversion sequence. If a function that uses the
ambiguous conversion sequence is selected as the best viable function,
the call will be ill-formed because the conversion of one of the
arguments in the call is ambiguous.
Here, B::operator<<(int) is the only viable candidate - and hence is the best viable candidate, even though the conversion sequence for the parameter is the ambiguous conversion sequence. According to the bolded sentence, then, the call should be ill-formed because "the conversion of one of the arguments in the call is ambiguous".
Yet no compiler that I tested (g++, clang, and MSVC) actually reports an error, which makes sense because after the function to call is selected through overload resolution, the function's "parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding
argument" (§5.2.2 [expr.call]/p4). This initialization is copy-initialization (§8.5 [dcl.init]/p15), and according to §8.5 [dcl.init]/p17, results in a new round of overload resolution to determine the conversion function to use:
The semantics of initializers are as follows. The destination type
is the type of the object or reference being initialized and the
source type is the type of the initializer expression. If the initializer is not a single (possibly parenthesized) expression, the
source type is not defined.
[...]
If the destination type is a (possibly cv-qualified) class type: [...]
Otherwise, if the source type is a (possibly cv-qualified) class type, conversion functions are considered. The applicable conversion
functions are enumerated (13.3.1.5), and the best one is chosen
through overload resolution (13.3). The user-defined conversion so
selected is called to convert the initializer expression into the
object being initialized. If the conversion cannot be done or is
ambiguous, the initialization is ill-formed.
[...]
And in this round of overload resolution, there is a tiebreaker in §13.3.3 [over.match.best]/p1:
a viable function F1 is defined to be a better function than another
viable function F2 if for all arguments i, ICSi(F1) is not a worse
conversion sequence than ICSi(F2), and then
for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2), or, if not that,
the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the
entity being initialized) is a better conversion sequence than the
standard conversion sequence from the return type of F2 to the
destination type.
(Example and remainder of the list omitted)
Since the standard conversion sequence from int to int (Exact Match rank) is better than the standard conversion sequence from char to int (Promotion rank), the first beats the second, and there should be no ambiguity - the conversion defined by operator int() will be used for the initialization, which then contradicts the sentence in §13.3.3.1 [over.best.ics]/p10 that says the function call will be ill-formed because of ambiguity.
Is there anything wrong in the above analysis, or is that sentence a bug in the standard?
When deciding the best user-defined conversion for a user-defined conversion sequence we have an overload candidate set.
§13.3.3/p1 says:
Define ICSi(F) as follows:
[...]
let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the
type of the i-th parameter of viable function F. 13.3.3.1 defines the implicit conversion sequences and
13.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence
or worse conversion sequence than another.
Given these definitions, a viable function F1 is defined to be a better function than another viable function
F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
— [...]
— the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the
standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the
entity being initialized) is a better conversion sequence than the standard conversion sequence from
the return type of F2 to the destination type.
This applies since
§13.3.3.1.2/p2
2 The second standard conversion sequence converts the result of the user-defined conversion to the target
type for the sequence. Since an implicit conversion sequence is an initialization, the special rules for
initialization by user-defined conversion apply when selecting the best user-defined conversion for a user-defined
conversion sequence (see 13.3.3 and 13.3.3.1).
and therefore the conversion sequence involving operator int is selected as best match.
Finally I would rephrase §13.3.3.1/p10 as
If several different sequences of conversions exist that each convert the argument to the parameter type and it was not possible to determine a best candidate,
the implicit conversion sequence associated with the parameter is defined to be the unique conversion sequence
designated the ambiguous conversion sequence. For the purpose of ranking implicit conversion sequences
as described in 13.3.3.2, the ambiguous conversion sequence is treated as a user-defined sequence that is
indistinguishable from any other user-defined conversion sequence134. If a function that uses the ambiguous
conversion sequence is selected as the best viable function, the call will be ill-formed because the conversion
of one of the arguments in the call is ambiguous.

Should this compile? Overload resolution and implicit conversions

This example seems to compile with VC10 and gcc (though my version of gcc is very old).
EDIT: R. Martinho Fernandez tried this on gcc 4.7 and the behaviour is still the same.
struct Base
{
operator double() const { return 0.0; }
};
struct foo
{
foo(const char* c) {}
};
struct Something : public Base
{
void operator[](const foo& f) {}
};
int main()
{
Something d;
d["32"];
return 0;
}
But clang complains:
test4.cpp:19:6: error: use of overloaded operator '[]' is ambiguous (with operand types 'Something' and 'const char [3]')
d["32"]
~^~~~~
test4.cpp:13:10: note: candidate function
void operator[](const foo& f) {}
^
test4.cpp:19:6: note: built-in candidate operator[](long, const char *)
d["32"]
^
test4.cpp:19:6: note: built-in candidate operator[](long, const restrict char *)
test4.cpp:19:6: note: built-in candidate operator[](long, const volatile char *)
test4.cpp:19:6: note: built-in candidate operator[](long, const volatile restrict char *)
The overload resolution is considering two possible functions from looking at this expression:
calling Something::operator[] (after a user defined conversion)
calling built in operator for const char* (think "32"[d]) (after a user defined conversion and standard conversion double to long).
If I had written d["32"] as d.operator[]("32"), then overload resolution won't even look at option 2, and clang will also compile fine.
EDIT: (clarification of questions)
This seems to be a complicated area in overload resolution, and because of that I'd appreciate very much answers that explain in detail the overload resolution in this case, and cite the standard (if there's some obscure/advanced likely to be unknown rule).
If clang is correct, I'm also interested in knowing why the two are ambiguous / one is not preferred over another. The answer likely would have to explain how overload resolution considers implicit conversions (both user defined and standard conversions) involved on the two candidates and why one is not better than the other.
Note: if operator double() is changed to operator bool(), all three (clang, vc, gcc) will refuse to compile with similar ambiguous error.
It should be easier to picture why the overload resolution is ambiguous by going through it step-by-step.
§13.5.5 [over.sub]
Thus, a subscripting expression x[y] is interpreted as x.operator[](y) for a class object x of type T if T::operator[](T1) exists and if the operator is selected as the best match function by the overload resolution mechanism (13.3.3).
Now, we first need an overload set. That's constructed according to §13.3.1 and contains member aswell as non-member functions. See this answer of mine for a more detailed explanation.
§13.3.1 [over.match.funcs]
p2 The set of candidate functions can contain both member and non-member functions to be resolved against the same argument list. So that argument and parameter lists are comparable within this heterogeneous set, a member function is considered to have an extra parameter, called the implicit object parameter, which represents the object for which the member function has been called. [...]
p3 Similarly, when appropriate, the context can construct an argument list that contains an implied object argument to denote the object to be operated on.
// abstract overload set (return types omitted since irrelevant)
f1(Something&, foo const&); // linked to Something::operator[](foo const&)
f2(std::ptrdiff_t, char const*); // linked to operator[](std::ptrdiff_t, char const*)
f3(char const*, std::ptrdiff_t); // linked to operator[](char const*, std::ptrdiff_t)
Then, an argument list is constructed:
// abstract argument list
(Something&, char const[3]) // 'Something&' is the implied object argument
And then the argument list is tested against every member of the overload set:
f1 -> identity match on argument 1, conversion required for argument 2
f2 -> conversion required for argument 1, conversion required for argument 2 (decay)
f3 -> argument 1 incompatible, argument 2 incompatible, discarded
Then, since we found out that there are implicit conversions required, we take a look at §13.3.3 [over.match.best] p1:
Define ICSi(F) as follows:
if F is a static member function, [...]; otherwise,
let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the type of the i-th parameter of viable function F. 13.3.3.1 defines the implicit conversion sequences and 13.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence or worse conversion sequence than another.
Now let's construct those implicit conversion sequences for f1 and f2 in the overload set (§13.3.3.1):
ICS1(f1): 'Something&' -> 'Someting&', standard conversion sequence
ICS2(f1): 'char const[3]' -> 'foo const&', user-defined conversion sequence
ICS1(f2): 'Something&' -> 'std::ptrdiff_t', user-defined conversion sequence
ICS2(f2): 'char const[3]' -> 'char const*', standard conversion sequence
§13.3.3.2 [over.ics.rank] p2
a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence.
So ICS1(f1) is better than ICS1(f2) and ICS2(f1) is worse than ICS2(f2).
Conversely, ICS1(f2) is worse than ICS1(f1) and ICS2(f2) is better than ICS2(f1).
§13.3.3 [over.match.best]
p1 (cont.) Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then [...]
p2 If there is exactly one viable function that is a better function than all other viable functions, then it is the one selected by overload resolution; otherwise the call is ill-formed.
Well, f*ck. :) As such, Clang is correct in rejecting that code.
It seems there is no question that both Something::operator[](const foo& f) and the built-in operator[](long, const char *) are viable candidate functions (13.3.2) for overload resolution. The types of real arguments are Something and const char*, and implicit conversion sequences (ICFs) I think are:
for Something::operator[](const foo& f): (1-1) identity conversion, and (1-2) foo("32") through foo::foo(const char*);
for operator[](long, const char *): (2-1) long(double(d)) through Something::operator double() const (inherited from Base), and (2-2) identity conversion.
Now if we rank these ICFs according to (13.3.3.2), we can see that (1-1) is a better conversion than (2-1), and (1-2) is a worse conversion than (2-2). According to the definition in (13.3.3),
a viable function F1 is defined to be a better function than another viable function
F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), ...
Therefore, neither of the considered two candidate functions is better than the other one, and thus the call is ill-formed. I.e. Clang appears to be correct, and the code should not compile.
It would seem from 13.6 in the C++11 spec that clang is correct here:
13.6
Built-in operators
[over.built]
The candidate operator functions that represent the built-in operators defined in Clause 5 are specified in
this subclause. These candidate functions participate in the operator overload resolution process as described
in 13.3.1.2 and are used for no other purpose. [ Note: Because built-in operators take only operands with
non-class type, and operator overload resolution occurs only when an operand expression originally has class
or enumeration type, operator overload resolution can resolve to a built-in operator only when an operand
has a class type that has a user-defined conversion to a non-class type appropriate for the operator, or when
an operand has an enumeration type that can be converted to a type appropriate for the operator. Also note
that some of the candidate operator functions given in this subclause are more permissive than the built-in
operators themselves. As described in 13.3.1.2, after a built-in operator is selected by overload resolution
the expression is subject to the requirements for the built-in operator given in Clause 5, and therefore to
any additional semantic constraints given there. If there is a user-written candidate with the same name
and parameter types as a built-in candidate operator function, the built-in operator function is hidden and
is not included in the set of candidate functions. — end note ]
:
For every cv-qualified or cv-unqualified object type T there exist candidate operator functions of the form
T& operator[](T *, std::ptrdiff_t);
T& operator[](std::ptrdiff_t, T *);
edit
Once you get past which operator functions exist, this just becomes standard overload resolution as described by section 13.3 of the standard -- about 10 pages of details, but the gist of it is that for a function call to not be ambiguous, there needs to be a single function that is at least as good a match as all the possible, viable functions on every argument, and a better match than the others on at least one argument. There's a lot of spec detail on exactly what 'better' means, but it boils down to (in this case) a match not requiring any user-defined conversion operator or object constructor is better than one which does.
So in this case, there are two viable matches:
void Something::operator[](const foo& f)
operator[](long, const char *)
The first is a better match for the first argument, while the second is a better match for the second. So unless there's some other function that is better than both of these, its ambiguous.
That latter point is a possble workaround -- add:
void operator[](const char *a) { return (*this)[foo(a)]; }
to class Something

Overload resolution and arrays: which function should be called?

Consider the following program:
#include <cstddef>
#include <cstdio>
void f(char const*&&) { std::puts("char const*&&"); } // (1)
void f(char const* const&) { std::puts("char const* const&"); } // (2)
template <std::size_t N>
void f(char const (&)[N]) { std::puts("char const(&)[N]"); } // (3)
int main()
{
const char data[] = "a";
f(data);
}
Which f should be called? Why?
The latest released versions of three compilers disagree on the answer to this question:
(1) is called when the program is compiled using g++ 4.5.2
(2) is called when the program is compiled using Visual C++ 2010 SP1
(3) is called when the program is compiled using Clang 3.0 (trunk 127530)
Have the overload resolution rules changed substantially in different C++0x drafts? Or, are two of these compilers really just completely wrong? Which overload is the correct overload to be selected per the latest C++0x draft?
First, the conversion sequence of all three is the same, except that for the first two, there is an lvalue transformation (lvalue to rvalue conversion), which however is not used in ordering conversion sequences. All three are exact matches (the function template specialization has parameter type char const(&)[2]).
If you iterate over the rules at 13.3.3.2p3, you stop at this paragraph
S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference.
A conversion sequence cannot be formed if it requires binding an rvalue reference to an lvalue, the spec says at 13.3.3.1.4p3. If you look at how reference binding works at 8.5.3p5 last bullet, it will create a temporary (I think they meant rvalue temporary) of type char const* from the array lvalue and bind the reference to that temporary. Therefor, I think (1) is better than (2). Same holds for (1) against (3), although we wouldn't need this because (3) is a template so in a tie, we would choose (1) again.
In n3225, they changed the reference binding rules so that rvalue references can bind to initializer expressions that are lvalues, as long as the reference will be bound to an rvalue (possibly created by converting the initializer properly before). This could influence the handling by Visual C++, which may not be up to date here.
I'm not sure about clang. Even if it would ignore (1), then it would end up in a tie between (2) and (3), and would need to choose (2) because it's a non-template.
I think that 8.5.3p5 last bullet is confusing because it says "Otherwise a temporary of type ..". It's not clear whether the temporary is regarded as an lvalue or as an rvalue by 13.3.3.1.4p3, which means I'm not sure how the following should really behave according to the exact words of the spec
void f(int &);
void f(int &&);
int main() {
int n = 0;
f(n);
}
If we assume the temporary is treated as an rvalue by clause 13, then we bind an rvalue ref to an rvalue in the second function and an lvalue in the first. Therefor, we will choose the second function and then get a diagnostic by 8.5.3p5 last bullet because T1 and T2 are reference-related. If we assume the temporary is treated as an lvalue by clause 13, then the following would not work
void f(int &&);
int main() {
f(0);
}
Because we would bind an rvalue ref to an lvalue which by clause 13 will make the function non-viable. And if we interpret "binding an rvalue ref to an lvalue" to refer to the initializer expression instead of the final expression bound to, we won't accept the following
void f(float &&);
int main() {
int n = 0;
f(n);
}
This however is valid as of n3225. So there seems to be some confusion - I sent a DR to the committee about this.
I claim that #3 is the function chosen by a conforming compiler.
(1) is better than (2) because "Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference."
(3) is better than both (1) and (2) because it is an identity conversion (the others are exact match conversions) and "Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence)"
Template vs non-template is only considered when neither conversion is better "or, if not that..."
oddly enough though, Comeau prefers (2) over (3). This test case fails to compile:
#include <cstddef>
#include <cstdio>
// (1) removed because Comeau doesn't support rvalue-references yet
char f(char const* const&) { std::puts("char const* const&"); return 0; } // (2)
template <std::size_t N>
int f(char const (&)[N]) { std::puts("char const(&)[N]"); return 0; } // (3)
int main()
{
const char data[] = "a";
switch (0) {
case sizeof(char):
break;
case sizeof(f(data)):
break;
}
}
This is a community wiki answer for collecting snippets from the standard (draft 3225).
section 13.3.3 "Best viable function" [over.match.best]
Define ICSi(F) as follows:
if F is a static member function, ICS1(F) is defined such that ICS1(F) is neither better nor worse than
ICS1(G) for any function G, and, symmetrically, ICS1(G) is neither better nor worse than ICS1(F); otherwise,
let ICSi(F) denote the implicit conversion sequence that converts the i-th argument in the list to the
type of the i-th parameter of viable function F. 13.3.3.1 defines the implicit conversion sequences and
13.3.3.2 defines what it means for one implicit conversion sequence to be a better conversion sequence or worse conversion sequence than another.
Given these definitions, a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than ICSi(F2), and then
for some argument j, ICSj(F1) is a better conversion sequence than ICSj(F2)
or, if not that,
the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the entity being initialized) is a better conversion sequence than the standard conversion sequence from the return type of F2 to the destination type
or, if not that,
F1 is a non-template function and F2 is a function template specialization
or, if not that,
F1 and F2 are function template specializations, and the function template for F1 is more specialized
than the template for F2 according to the partial ordering rules described in 14.5.6.2.
If there is exactly one viable function that is a better function than all other viable functions, then it is the one selected by overload resolution; otherwise the call is ill-formed.
section 13.3.3.1.4 "Reference binding" [over.ics.ref]
When a parameter of reference type binds directly (8.5.3) to an argument expression, the implicit conversion
sequence is the identity conversion, unless the argument expression has a type that is a derived class of the
parameter type, in which case the implicit conversion sequence is a derived-to-base conversion (13.3.3.1). If the parameter binds directly to the result of applying a conversion function to the
argument expression, the implicit conversion sequence is a user-defined conversion sequence (13.3.3.1.2), with the second standard conversion sequence either an identity conversion or, if the conversion function
returns an entity of a type that is a derived class of the parameter type, a derived-to-base Conversion.
When a parameter of reference type is not bound directly to an argument expression, the conversion sequence
is the one required to convert the argument expression to the underlying type of the reference according
to 13.3.3.1. Conceptually, this conversion sequence corresponds to copy-initializing a temporary of the
underlying type with the argument expression. Any difference in top-level cv-qualification is subsumed by
the initialization itself and does not constitute a conversion.
section 13.3.3.2 "Ranking implicit conversion sequences" [over.ics.rank]
13.3.3.2 defines a partial ordering of implicit conversion sequences based on the relationships better conversion
sequence and better conversion. If an implicit conversion sequence S1 is defined by these rules to be a better
conversion sequence than S2, then it is also the case that S2 is a worse conversion sequence than S1. If
conversion sequence S1 is neither better than nor worse than conversion sequence S2, S1 and S2 are said to
be indistinguishable conversion sequences.
When comparing the basic forms of implicit conversion sequences (as defined in 13.3.3.1)
a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence, and
a user-defined conversion sequence (13.3.3.1.2) is a better conversion sequence than an ellipsis conversion sequence (13.3.3.1.3).
Two implicit conversion sequences of the same form are indistinguishable conversion sequences unless one of
the following rules applies:
Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if
S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by 13.3.3.1.1, excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence)
or, if not that,
the rank of S1 is better than the rank of S2, or S1 and S2 have the same rank and are distinguishable by the rules in the paragraph below
or, if not that,
S1 and S2 differ only in their qualification conversion and yield similar types T1 and T2 (4.4), respectively, and the cv-qualification signature of type T1 is a proper subset of the cv-qualification signature of type T2.
or, if not that,
S1 and S2 are reference bindings (8.5.3) and neither refers to an implicit object parameter of a
non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to
an rvalue and S2 binds an lvalue reference.