Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does this typedef and conversion operator syntax mean?

Tags:

c++

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?

like image 420
Collin Avatar asked Aug 12 '26 10:08

Collin


1 Answers

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.

like image 67
bolov Avatar answered Aug 14 '26 10:08

bolov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!