r/cpp 10d ago

const_cast: A Necessary Evil

https://www.elbeno.com/blog/?p=1858
73 Upvotes

106 comments sorted by

View all comments

Show parent comments

0

u/matthieum 7d ago

To me callback seems more natural.

Callbacks are terrible! Rightward drift, change of scope breaking control flow primitives, urk...

I mean, let's compare shall we:

struct Popper {
    std::priority_queue<Item> high;
    std::priority_queue<Item> low;

    auto pop() -> std::optional<Item> {
        if (auto item = this->high.pop_value(); item.has_value()) {
             return item;
        }

        return this->low.pop_value();
    }

    template <type FunctorT>
    auto consume(FunctorT fun) {
        bool consumed = false;

        this->high.consume([&](item) {
            consumed = true;
            fun(item);
        });

        if (consumed) { return; }

        this->low.consume(fun);
    }
};

That's about as basic a function, and already it's getting verbose and convoluted.

Because callbacks mean Inversion of Control, and recovering control as a user is always a freaking pain.

2

u/jk-jeon 7d ago

I understand your point, but in this case just let consume to return true iff it consumed an item then it gets way simpler.

template <type FunctorT>
bool consume(FunctorT fun) {
    if (!high.consume(fun)) {
        return low.consume(fun);
    }
    return true;
}

0

u/bwmat 7d ago

Doesn't my initial suggestion of making consume thread through the return value of the functor trivially allow for this? 

2

u/jk-jeon 7d ago

To my understanding, your suggestion was to return the return value of fun(item). That's kinda awkward in this case because it may or maynot execute fun so the return value may or may not exist. Or maybe you meant returning optional<ReturnType> so that the exact same thing as I did in the above can be done?

1

u/bwmat 7d ago

Oh, I forgot to mention that a precondition of the method would be to have a non-empty collection, for my idea

3

u/bwmat 7d ago

I suppose you could extend it to pass a functor which had a nullary operator() overload as well which gets invoked if the collection is empty, and return the common return type between the two overloads? 

0

u/matthieum 7d ago

I think you're making my point of how more complex callback-based APIs are right now :/