I've run across a class which wraps a boost::shared_ptr and am having trouble understanding what the conversion operator does and how it works specifically. The class:
class TestWrapper {
public:
explicit TestWrapper(int* ptr) : internal(ptr) {}
typedef boost::shared_ptr<int> TestWrapper::* safe_bool;
boost::shared_ptr<int> internal;
bool operator!() { return !internal; }
operator safe_bool() const { return internal ? &TestWrapper::internal : 0; }
};
The code makes tests like the following work as if they were testing the nullness of the wrapped pointer like so:
TestWrapper t(new int(5));
if(!t) {
std::cout << "!null" << std::endl;
}
if(t) {
std::cout << "null" << std::endl;
}
However, I've been unable to wrap my head around what the typedef means:
typedef boost::shared_ptr<int> TestWrapper::* safe_bool;
It doesn't look like a rename of boost::shared_ptr, it doesn't look like a function pointer (which requires parentheses?). What is it?
I also can't figure out what the conversion operator means:
operator safe_bool() const { return internal ? &TestWrapper::internal : 0; }
What is &TestWrapper::internal? Why is it the same type as the typedef? Why can 0 be converted to it?
boost::shared_ptr<int> TestWrapper::*
This is a class data member pointer. It points to a data member from class TestWrapper of type boost::shared_ptr<int>
Let's give a simpler example with class data member pointers:
int X::*
This is a class data member pointer to a data member of type int in a class X so for instance you can do:
struct X
{
int a;
int b;
float c;
};
struct Y
{
int a;
};
auto test()
{
using T = int X::*; // a pointer to an int data member of class X
X x1{1, 2};
X x2{100, 200};
T pa = &X::a; // pointer to data member a of class X
T pb = &X::b; // pointer to data member b of class X
T pc = &X::c; // illegal
T py = &Y::a; // illegal
std::cout << x1.*pa; // 1
std::cout << x1.*pb; // 2
std::cout << x2.*pa; // 100
std::cout << x2.*pb; // 200
}
operator safe_bool() const
This is a conversion operator to the mentioned class data member pointer type.
What is
&TestWrapper::internal
Is the address of the data member internal of the class TestWrapper
Why is it the same type as the typedef
Because internal is a class data member of type boost::shared_ptr<int> of class TestWrapper
Why can 0 be converted to it
Being a pointer, you can assign nullptr to it. Or, as the code does, you can assign 0 to it. This operator returns a pointer to the data member internal only if (bool) internal != false, else it returns the null pointer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With