This question already has an answer here:
Why does pointer decay take priority over a deduced template?
(1 answer)
Closed 7 years ago.
I have simple question about the c++ function match priority. Suppose I have such code:
#include <iostream>
void func(const char*)
{
std::cout << "const char*" << std::endl;
}
template<int N>
void func(const char (&) [N])
{
std::cout << "const char (&) [N]" << std::endl;
}
int main(int argc, char* argv[])
{
func("Hello world");
return 0;
}
The result of the code is (with Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)):
const char*
I think the literal type of the "Hello world" should be const char[]. Why the const char* version has a higher priority than the const char (&)[] version?
Overload resolution attempts to find the best conversion. The following paragraph lists the relevant bullet points that could distinguish both conversions:
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,
[…]
While the specialization of the function template yields a parameter with an identity conversion, the non-template overload with char const* requires an Array-to-pointer conversion. Intuitively, we'd say that the former is a better match and should thus be selected. However, the array-to-pointer conversion is an Lvalue Transformation, excluded from the first bullet point. And since it has Exact Match Rank, the rank of the conversion isn't different than the rank of the conversion for char const (&)[N], which also has Exact Match Rank. "The rules in the paragraph below" cannot distinguish the conversions either, as they solely address derived-to-base conversions and such, but not array-to-pointer.
In fact, the conversion to char const (&)[N] is not better in any way. But overload resolution discriminates templates:
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,
[…]
F1
is not a function template specialization and F2 is a function
template specialization, or, if not that,
Hence the non-template overload is selected.
In your particular case the relevant part of the resolution rules applied is that non-template functions have precedence over template functions, that's why you see a pointer and not an array reference.
Related
#include <iostream>
#define FUNC() { std::cout << __PRETTY_FUNCTION__ << "\n"; }
void foo(char const*&& ) FUNC() // A
void foo(char const(&)[4]) FUNC() // B
int main()
{
foo("bar");
}
Demo
When using an rvalue reference in the parameter type of the first overload (A), clang current master unambiguously chooses that overload A over B. GCC current master on the other hand complains about an ambiguity.
I'm quite surprised that the string literal, being an lvalue of 4 char const ([expr.prim.literal]/1, [lex.string]/6) should prefer the array-to-pointer conversion on overload A over the identity conversion on overload B.
Without the rvalue reference, that is void foo(char const*), both GCC and clang reject the call as ambiguous. That's also something I don't fully understand, since I would have guessed that there's still an array-to-pointer conversion and therefore [over.ics.rank]p3.2.1 applies:
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 [over.ics.scs], excluding
any Lvalue Transformation; the identity conversion sequence is
considered to be a subsequence of any non-identity conversion
sequence) or, if not that,
What is going on in either case?
(This is only a partial answer, covering the second case)
What is going on in either case?
Regarding the second case, as to why the following overloads
void foo(char const* ) FUNC() // A
void foo(char const(&)[4]) FUNC() // B
yields ambiguous overloads (for both Clang and GCC); [over.ics.rank]/3.2.1 may seem to favour B, being an identity conversion, over A, requiring an array-to-pointer conversion which in turn is in the conversion category of Lvalue Transformation:
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 [over.ics.scs], excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence) or, if not that,
[...]
However, as I interpret the first emphasized segment above, Lvalue Transformation:s are excluded from both sequences S1 and S2 when applying [over.ics.rank]/3.2.1, and the second emphasized segment applies only after this exclusion has been applied.
As pointed out in a comment by #LanguageLawyer, that the rules indeed allow this ambiguity was highlighted in CWG 1789 which, afaict, have seen no progress or feedback since 2013.
1789. Array reference vs array decay in overload resolution
Section: 12.4.4.3 [over.ics.rank]
Status: drafting
Submitter: Faisal Vali
Date: 2013-10-01
The current rules make an example like
template<class T, size_t N> void foo(T (&)[N]);
template<class T> void foo(T *t);
int arr[3]{1, 2, 3};
foo(arr);
ambiguous, even though the first is an identity match and the second
requires an lvalue transformation. Is this desirable?
This question already has answers here:
Unexpected overload resolution in visual studio involving void*, string and const char[]
(3 answers)
Closed 7 years ago.
Why would the code give an output: bool ?
Is there any way I could make the const char* to match the string version?
#include <string>
#include <iostream>
void func(bool)
{
std::cout << "bool" << std::endl;
}
void func(const std::string&)
{
std::cout << "string" << std::endl;
}
int main(int argc, char* argv[])
{
func("hello");
}
This happens because the compiler will prefer built-in conversions to user-defined conversions. The conversion from a pointer to a bool is built-in, so that overload is selected rather than constructing a std::string.
You could add an overload which takes a const char* and forwards it to the std::string version:
void func(const char* arg)
{
func(std::string{arg});
}
To answer the why:
Function matching is the process by which the compiler selects which function to call among an overload set.
Here, there are two viable candidates (the two functions you defined). To pick one, the compiler ranks the conversion they imply.
The first candidate void func(bool) implies an array-to-pointer conversion followed by a boolean conversion (from const char[6] to const char* to bool)
The second candidate implies a user-defined conversion (calling the std::string ctor taking a const char*)
The second conversion has lower ranking, so the first candidate is selected as the best match.
According to the standard N4431 §13.3.3.2/2 Ranking implicit conversion sequences [over.ics.rank] (emphasis mine):
When comparing the basic forms of implicit conversion sequences (as
defined in 13.3.3.1) (2.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 (2.2) — 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).
Consequently, because the char const * to bool is a standard implicit conversion compared to the implicit conversion to std::string which is a user-defined conversion is a better conversion and is preferred in overload resolution.
In order to force overload resolution to choose the std::string version:
func(std::string("hello"));
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 (...).
#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.
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.