Transparently insert temporary data into the call area

In C ++, operator-> has special semantics, because if the return type is not a pointer, it will again call operator-> on that type. But the intermediate value is stored as a temporary calling expression. This allows the code to detect changes in the return 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 the T elements can be accessed transparently:

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

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

EDIT: Another issue I ran into is in expressions like

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

because when arrow_helper from the second operator-> destroyed, it again overwrites the value back to the original. My semi-elegant solution for arrow_helper have hidden T orig and assert(orig == *owner) in the destructor.

+5
source share
2 answers

There is no guarantee that all changes will be detected:

 Foo &x = f->bar; x = 6; /* undetected change */ 
+3
source

If there is no way to get a link to any data in the T interface via T or otherwise, I think it should be safe. If there is any way to capture such a pointer or link, you are done and undefined as soon as someone saves that link and uses it later.

0
source

Source: https://habr.com/ru/post/1213626/


All Articles