On 12/3/23 01:31, Andrzej Krzemienski wrote:
sob., 2 gru 2023 o 22:20 Andrey Semashev via Boost
mailto:boost@lists.boost.org> napisał(a): On 12/2/23 23:12, Andrzej Krzemienski via Boost wrote: > Hi All, > Two observations from reading the docs. > > Why do I need a condition in scope_exit when I have a scope_fail?
There is a discussion about this in this section:
https://lastique.github.io/scope/libs/scope/doc/html/scope/scope_guards.html... https://lastique.github.io/scope/libs/scope/doc/html/scope/scope_guards.html...
In short, scope_fail implies processing a failure event (for whatever definition of "failure") and scope_exit has no such connotation and can be used with arbitrary conditions. The different scope guards have different default conditions, too.
Having read the linked section as well as your reply, I still do not understand the need for a scope_exit with a failure condition. I either want to *always* call the callback function on scope exit, or only under some condition. If it is under some condition, I would call scope_failure or scope_success respectively.
Or are you saying that sometimes I want to call or skip the call based on random conditions not having to do with failing anything, and where the set_active would not work? Is that it? Do you have any convincing examples for this?
I do not have a real life use case but I also don't think that every condition must fall in the success/failure category. For example, you could log the state of your program in certain conditions, which are not necessarily a failure. class processor { private: std::queue<request> m_requests; bool m_interrupt; public: void enqueue_request(request const& req); void process_requests() { scope_exit logging_guard { [this] { // Log the state whether or not we're leaving // with an exception std::cout << m_requests.size() << " unprocessed requests left" << std::endl; }, [this] { return !m_requests.empty(); } }; while (!m_interrupt && !m_requests.empty()) { BOOST_SCOPE_FINAL [this] { m_requests.pop(); }; m_requests.front().process(); // may throw } } }; It is true that sometimes this can be achieved by using set_active() or even merging the condition into the action, but there may be cases when that is not convenient. Calling set_active needs to be done manually at every return point, which is error-prone. Merging the condition into action may be messy, especially if the condition is not so trivial and needs to be used in multiple scope guards. You can move the condition into a separate function object and reuse it with different actions. In any case, the support for condition function objects is needed by the library anyway, it's not like that functionality is unused. I don't see the reason to actively hide it from users.