ScopeSuccess C++ 17

suggest change

Thanks to int std::uncaught_exceptions(), we can implement action which executes only on success (no thrown exception in scope). Previously bool std::uncaught_exception() just allows to detect if any stack unwinding is running.

#include <exception>
#include <iostream>

template <typename F>
class ScopeSuccess
{
private:
    F f;
    int uncaughtExceptionCount = std::uncaught_exceptions();
public:
    explicit ScopeSuccess(const F& f) : f(f) {}
    ScopeSuccess(const ScopeSuccess&) = delete;
    ScopeSuccess& operator =(const ScopeSuccess&) = delete;

    // f() might throw, as it can be caught normally.
    ~ScopeSuccess() noexcept(noexcept(f())) {
        if (uncaughtExceptionCount == std::uncaught_exceptions()) {
            f();
        }
    }
};

struct Foo {
    ~Foo() {
        try {
            ScopeSuccess logSuccess{[](){std::cout << "Success 1\n";}};
            // Scope succeeds,
            // even if Foo is destroyed during stack unwinding
            // (so when 0 < std::uncaught_exceptions())
            // (or previously std::uncaught_exception() == true)
        } catch (...) {
        }
        try {
            ScopeSuccess logSuccess{[](){std::cout << "Success 2\n";}};

            throw std::runtime_error("Failed"); // returned value
                                                // of std::uncaught_exceptions increases
        } catch (...) { // returned value of std::uncaught_exceptions decreases
        }
    }

};

int main()
{
    try {
        Foo foo;

        throw std::runtime_error("Failed"); // std::uncaught_exceptions() == 1
    } catch (...) { // std::uncaught_exceptions() == 0
    }
}

Output:

Success 1

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


RAII:
* ScopeSuccess C++ 17

Table Of Contents
8 Arrays
11 Loops
39 Streams
51 Unions
56 Lambdas
60 SFINAE
62 RAII
67 Sorting
84 RTTI
87 Scopes
104 Profiling
107 Recursion
117 Iteration
125 Alignment
134 Semaphore
136 Debugging
139 Mutexes
142 decltype