C++ Logo


Advanced search

Re: The intercept operators

From: organicoman <organicoman_at_[hidden]>
Date: Sun, 27 Dec 2020 17:24:18 +0100
Thanks for the reply,I checked the paper, it has the same way of chaining the calls to each operator.() down the classes (drill down), but it doesn't allow any capture of the type of member it is called for, i.e you cannot tell if you calling that overloaded operator on a member data or a member function exactly the same behavior as the operator->() which calls itself on the returned type unless it is not of class type.So other than the observation about trying to call the member function from inside the operator.(), i think that this way of implementation gives the power to inspect the referred member before executing it.I know it will need some gymnastics to be more aligned with the standard but is it worth it?CheersSent from my Galaxy
-------- Original message --------From: Jason McKesson via Std-Proposals <std-proposals_at_[hidden]> Date: 12/27/20 4:23 PM (GMT+01:00) To: std-proposals_at_[hidden] Cc: Jason McKesson <jmckesson_at_[hidden]> Subject: Re: [std-proposals] The intercept operators On Sun, Dec 27, 2020 at 9:43 AM chibane nadir via Std-Proposals<std-proposals_at_[hidden]> wrote:>> Hello Gents,> I wonder why we cannot allow the overload of the member access operators (. ->) if we know They will be of extreme usefulness.> Take this case of usage:> I'm implementing a class called "container_slice", since it is a slice of some class, then it should have all its members, and behave exactly as it (picture a slice of a cake has the same taste of the cake and the same appearance) obviously it should inherit from it.> I declared it as follow:>> template <typename Container>> class container_slice : public Container> {> static_assert(is_container_v<Container>); // metafunction to tell if a class is a standard container, easy to implement>> typename Container::iterator m_begin;> typename Container::iterator m_end;>> public:> using Container::Container; // import all base class constructors>> /*> * this constructor memcpy the container 'c' in the memory allocated for the base class of this instance, and sets the bounds of this> * slice (the range)> */> container_slice(const Container& c, typename Container::iterator _beg, typename Container::iterator _end);>> void detach(); // make this slice a separate copy of the range it views.> typename Container::iterator begin(); // returns: m_begin> typename Container::iterator end(); // returns: m_end> };>> as you can see, this class has the same member functions of its base class, which allow it to behave as a container and also as a view onto a container ( using this class constructor)>> what i want to do is to capture the calls to the base class member functions, like wise when the called member function is modifying (that is change the values or memory address of the referred container) i will call 'detach()' member function, which will copy the range of values it views, from the referred container into a new store to make it a clone (Copy on Write)>> There is no way to capture and tell if the called member function is a modifying member function or a const member function. Nor there is a way to do some logic before calling these member functions.> the only trick that can capture it, is at its call site i.e when we use the (.)member access operator and (->) arrow member access operator. expl:>> imagine i can overload the member access operator (.) like the following:>> template<typename T, typename Ret, typename ...Args>> constexpr Ret container_slice::operator . (T container_slice::* member, Args&& ...arg) //the same for operator->> {> if constexpr(std::is_const_member_function_pointer<decltype(member)>::value) // meta function easy to implement> return this->member(std::forward<Args>(arg),...);> else> {> this->detach(); // clone in a separate store (copy on write), then act upon> return this->member(std::forward<Args>(arg),...);> }> }>> It is clear that the code above intercept the call to the member function and depending on its nature (const or not) does actions, Like copy on write for example, and there are so many usage with the same technique.>> Of course the goal of this, is to avoid writing the same API of the base Container just for the sake of capturing the non 'const' members.> As you know there are a couple of std-containers and each has a relatively different API. So rewrite each of them is code duplication and a waist of time.>> I call this kind of overload: "the intercept operators".>> Ok folks, does anyone think that this proposal should be presented to the comity?Overloading operator-dot has been proposed several times, in manyforms. All of these proposals have eventually died in committee forvarious reasons. The last one was 3 years ago.Note that Stroustrup's operator-dot would not work in your case,because by default, any `object.name` will access `name` from theoverloaded return type, not from the class of `object`. So if there'sa conflict, the type being proxied has priority. Indeed, in thatproposal, guarantee-ably accessing a member of the proxy objectrequires oddball syntax.Also, your version of operator-dot is weird. Most versions ofoperator-dot express their semantics through some form of conversion.That is, the function return value returns a reference to the proxiedobject. Yours seems to want to actually invoke the function callthrough a pointer-to-member or something. That seems needlesslyovercomplicated.N4173 is the first operator-dot paper by Stroustrup, with P0252providing standard wording for it. P0352 is an alternative idea thatpiggybacks off of base class conversions to achieve a similar effect.-- Std-Proposals mailing listStd-Proposals_at_[hidden]://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2020-12-27 10:24:37