0

In C++, Is there a nice way of automatically running some routine when a function return or scoped routine goes outside?

Using goto statement seems to help, but it misses when an exception is thrown and not treated by catch or finally statement. Unfortunately, finally statement cannot be used in C++. RAII is another way of doing it, but it forces me to define a class every time, that is cumbersome than finally statement.

Hyunjik Bae
  • 2,721
  • 2
  • 22
  • 32

2 Answers2

0

If you are using c++/11, you could always create a generic, reusable class that runs any function in its destructor.

#include <iostream>
#include <functional>

class RAIIPattern final
{
public:
    typedef std::function<void()> Func_t;

    RAIIPattern(Func_t onExitScope) : m_onExitScope(onExitScope) { }

    ~RAIIPattern() {
        if (m_onExitScope) m_onExitScope();
    }

private:
    // No copy
    RAIIPattern(const RAIIPattern&);
    RAIIPattern& operator=(const RAIIPattern&);

    Func_t m_onExitScope; 
};

int main ()
{
    using namespace std;
    RAIIPattern onExit([] { cout << "on exit 1" << endl; });

    {
        RAIIPattern onExit([] { cout << "on exit 2" << endl; });
    }

    return 0;
}
Sebacote
  • 690
  • 6
  • 17
0

RAII is another way of doing it, but it forces me to define a class every time, that is cumbersome than finally statement.

You can use Boost.ScopeExit.

Or write your own generic solution, using std::function or lambdas. Here is the basic idea:

#include <iostream>

template <class Function>
class ScopeExit final
{
private:
    Function function;
public:
    ScopeExit(Function function) : function(function) {}
    ~ScopeExit() { function(); }

    ScopeExit(ScopeExit const&) = delete;
    ScopeExit &operator=(ScopeExit const&) = delete;
};

template <class Function>
ScopeExit<Function> MakeScopeExit(Function function)
{
    return ScopeExit<Function>(function);
}

int main()
{
    auto scope_exit = MakeScopeExit([]() { std::cout << "exit\n"; });

    std::cout << "function body\n";
}
Christian Hackl
  • 27,051
  • 3
  • 32
  • 62