If I have a struct A
defined as:
struct A {
const char *data;
operator const char * () const { return data; }
friend bool operator== (const A &s1, const char *s2)
{ return /* typical string comparison result */; }
};
And I write A{"hello"} == "test2"
, is A::operator==
called? What in the standard states that (and why isn't the A
implicitly converted to const char *
?)
What about "test2" == A{"hello"}
? Is the A
converted in this case?
EDIT: What about if struct A
also has member:
friend bool operator== (const char *s1, const A &s2)
When you do
A{"hello"} == "test2"
we perform overload resolution on operator==
. First, we find the viable candidates ([over.match.viable]), via name lookup:
operator==(A const&, const char*); // yours
operator==(const char*, const char*); // built-in
Next, we determine which candidate has the best implicit conversion sequence. This is the first tiebreaker in [over.match.best]:
Given these definitions, a viable function
F1
is defined to be a better function than another viable functionF2
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, [...]
Both operators are Exact Match on the 2nd argument. On the first argument, your operator==
is an Exact Match whereas the built-in requires a user-defined conversion. Exact Match is the best kind of conversion, and user-defined is the worst - hence, yours has the better conversion sequence and becomes the best viable function.
In broader terms, the A
isn't implicitly converted to a const char*
because there's a better option where it doesn't have to be.
When you do:
"test2" == A{"hello"};
Your candidate isn't viable - there is no implicit conversion from const char*
to A const&
(first argument), so the only viable candidate is the built-in comparison for const char*
, which requires the user-defined conversion from A
to const char*
.
If you'd like your A::operator==
to be invoked, you'd have to add a new overload for operator==(const char*, A const&)
.