Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transparently insert temporary into caller's scope

Tags:

c++

In C++, operator-> has special semantics, in that if the returned type isn't a pointer, it will call operator-> again on that type. But, the intermediate value is kept as a temporary by the calling expression. This allows code to detect changes in the returned value:

template<class T>
class wrapper
{
    // ...
    T val;

    struct arrow_helper
    {
        arrow_helper(const T& temp)
            : temp(temp){}
        T temp;
        T* operator->() { return &temp; }
        ~arrow_helper() { std::cout << "modified to " << temp << '\n'; }
    };

    arrow_helper operator->() { return{ val }; }
    //return const value to prevent mistakes
    const T operator*() const { return val; }
}

and then T's members can be accessed transparently:

wrapper<Foo> f(/*...*/);
f->bar = 6;

Is there anything that could go wrong from doing this? Also, is there a way to get this effect with functions other than operator->?

EDIT: Another issue I've come across is in expressions like

f->bar = f->bar + 6;

since when the arrow_helper from the second operator-> is destructed it re-overwrites the value back to the original. My semi-elegant solution is for arrow_helper to have a T orig that is hidden, and assert(orig == *owner) in the destructor.

like image 686
Dan Avatar asked Oct 19 '22 17:10

Dan


1 Answers

There is no guarantee that all changes will be caught:

Foo &x = f->bar;
x = 6; /* undetected change */
like image 153
Adam Sosnowski Avatar answered Oct 22 '22 21:10

Adam Sosnowski