Snippet
#include <iostream>
#include <optional>
template <typename T>
struct W {
operator T&() { return *t; }
operator bool() const {
std::cout << "called W bool operator\n";
return t != nullptr;
}
T* t;
};
int main() {
int x = 42;
W<int> w{};
w.t = &x;
if (auto w_value = w) {
std::cout << "w_value " << w_value << "\n";
} else {
std::cout << "w is empty" << "\n";
}
return 0;
}
Code is here godboldt
What I want here is that in if (auto w_value = w)
w
should be contextually convertible to bool, such that the assignment works.
This works as expected if the line operator T&() { return *t; }
will be commented out.
But when this line is enabled, the bool
conversion operator will not be called.
Is there a way to make this code work, such that if w
converts to true
, then a reference to t
will be assigned in the if-init expression?
I have c++20 at disposal.
Ted has done a great job of explaining why operator bool() const
isn't contextually called inside the if
.
Other ways to overcome that
define a non-const
overload
explicit operator bool() {
std::cout << "called W bool non-const operator\n";
return t != nullptr;
}
Use deduced-this from later C++ standard to define all the const, non-const, volatile, lvalue, and rvalue variations at once
template<typename Self>
explicit operator bool(this Self&& self) {
std::cout << "called deduced-W bool operator\n";
return self.t != nullptr;
}