I have user-defined type:
class String::CharProxy
{
public:
const char* operator&() const;
char* operator&();
operator char() const;
operator char&();
};
The problem is when I'm trying to perform some explicit casts, the wrong operator is called:
CharProxy p(...);
static_cast<char>(p); // operator char&() call instead of operator char() const
I want operator char() const
to be called when casting to char
and operator char&()
- when casting to char&
only.
Could anyone explain how this mechanism works? Am I mistaken anywhere?
In your static_cast
, both operator char() const
and operator char&()
are candidate functions as per [over.match.conv] because both char
and char&
are convertible to char
via a standard conversion sequence.
Between the two functions, the compiler then decides by standard overload resolution rules. In these, operator char&()
is found to be a better fit because its implicit this
parameter has the same cv-qualifiers as the object you're passing into it (that is: there is no const
qualifier on p
). You can explicitly call the other operator with
static_cast<char>(static_cast<CharProxy const &>(p));
But in more realistic terms: 1. user-defined conversion functions are a hornets' nest that are best avoided 99% of the time, and 2. if your operator char() const
has so different semantics from your operator char&()
that you cannot use the latter where you can use the former, that seems like a very dangerous thing you're building there. Certainly it's not POLA-compliant.