#include <cstdint>
#include <iostream>
struct a_struct {
int64_t* le_int;
bool not_ok;
a_struct() : le_int{ new int64_t(0) }, not_ok{ false } {}
~a_struct() { delete le_int; }
operator bool() const {
return !not_ok;
}
operator int64_t* () {
return le_int;
}
};
int main(int argc, char** argv) {
a_struct s;
s.not_ok = true;
if (!s)//<-
std::cout << "o no." << std::endl;
else if (s.not_ok)
std::cout << "waddu heck?" << std::endl;
return 0;
}
In this example the !s
resolution prefers the int64_t*()
operator over the const bool()
operator.
Why?
CodePudding user response:
This is the "initialization by conversion function" case for overload resolution: http://eel.is/c draft/over.match.conv
Both conversion functions are candidates because both are non-explicit and their return types are implicitly convertible to bool
. Overload resolution is then performed with the object expression s
as the argument, and the implied object parameter of the conversion functions as the parameters. The implied object parameter has type T
cv &
, where T
is the class.
Binding T&
to T
is better than binding T const&
to T
. This is one of the rules by which implicit conversion sequences are ranked. http://eel.is/c draft/over.ics.rank#3.2.6
Note that there is a tie-breaker rule involving the return types of the conversion functions. Such tie-breaker rules are only considered after ranking of implicit conversion sequences for each parameter fails to yield a best viable function on account of the fact that every parameter's implicit conversion sequence is neither better nor worse than the implicit conversion sequence for the corresponding parameter of the other function. Thus, only if both conversion functions have the same cv-qualification (resulting in identical implicit conversion sequences for the implied object parameter), the tie-breaker is reached. http://eel.is/c draft/over.match.best#general-2.2
CodePudding user response:
Since your object s is not const, it prefers the non-const way of calling the type cast operator. So, removing the const from your bool type cast operator does the trick.