5 ms·
Most of what the author complains about w.r.t callbacks is fixed with std::function and lambdas (member function pointer syntax is necessarily weird, because me
by unlinked_dll 7y ago
Most of what the author complains about w.r.t callbacks is fixed with std::function and lambdas (member function pointer syntax is necessarily weird, because methods aren't just normal functions). I definitely don't miss the days of std::bind. Nowadays you just do something like
using Callback = std::function<int(int)>; // or whatever
Callback cbk = [&](int i) { return instance.method(i); };
I've also seen some real evil hacks that rely on casting 0 as a pointer to a class and relying on the ABI's spec for vtable layout to calculate the pointer of the function as an offset from the `this` pointer. Because that's easier to remember than the syntax for pointer-to-member functions.
- a_t48 7y agoThere's also Callback cbk = std::bind_front(instance, Instance::method); in C++20. I'm going to ignore std::bind as it has weird conventions. :)
- PaulDavisThe1st 7y agoUsing lamdba's requires grappling with entirely new syntax compared to anything else in C++ (or C). Using various bind equivalents just requires you to know what you're doing: boost::function<int(int)> cbk = boost::bind (&SomeObject::some_method, instance_of_some_object); ... cbk (22); // invoke callback In addition, the author's complaints about nobody using ptr-to-method is absurd. Even in 2010, anyone using libsigc++ or its (few) equivalents was using them, which meant that any GUI app written using GTKmm was full of them. What's not to love?
- AnimalMuppet 7y agoWhat's so awful about pointer to member? I've used it a couple of times, and didn't think it was particularly weird. I mean, yes, I had to look up the syntax, but it was rather straightforward.
- gpderetta 7y agothere is nothing wrong with them, but pointers to member do not close over this, so you still need some form of binding to use them as callbacks.
- AnimalMuppet 7y agoWell, when you invoke a pointer to member, you need an actual object (a this) to invoke it on. So when the member runs, it has a this. But it sounds like what you want is a "handle" or some such term, by which you can invoke a member function on an object, and all you need to do so is the handle. That's a different problem than pointers to members are trying to solve, but you can do that quite easily with a function object. That's essentially a roll-your-own closure, and since you can define whatever data members you want, you can close over anything. One thing you have to watch out for, though, is lifetimes. C++ is not garbage-collected, and so it will not preserve an object just because another object has a pointer or reference to it. If you create a function object that captures a pointer to member, and a "this" to invoke it on, and the "this" gets destroyed, and then you use the function object, you're going to get chaos.
- WesternStar 7y agoIt is notable that this code forces a conversion to std::function which IIRC can actually require more space than the lambda it's attempting to store. For lambdas just use auto they don't have a type don't worry about their type.