Hacker News new | ask | show | jobs
by stormbrew 4642 days ago
Better would be to just have the Scope class take a single function to run and establish multiple stack entries for them. This would be my version:

  #include <cstdio>

  template <typename tFunc>
  class ScopeFunc {
  private:
    tFunc mFunc;

  public:
    ScopeFunc(tFunc func) : mFunc(func) {}

    ~ScopeFunc() {
      mFunc();
    }
  };

  template <typename tFunc>
  ScopeFunc<tFunc> on_return(tFunc func)
  {
    return ScopeFunc<tFunc>(func);
  }

  int main() {
    auto first = on_return([]() { std::puts("first"); });
    auto second = on_return([]() { std::puts("second"); });

    std::puts("Hello");
  }
Note that this is C++11, using lambdas. Also that the output will be reversed from your expectation since it's a lifo, but that's probably actually what you want for real deferred behaviour and not text output.

It also optimizes nicely, which yours may not because the loop unrolling may be complicated and there's a higher chance of aliasing of the function pointers in the vector:

  0000000000400600 <main>:
    400600:	53                   	push   %rbx
    400601:	bf e4 07 40 00       	mov    $0x4007e4,%edi
    400606:	e8 b5 ff ff ff       	callq  4005c0 <puts@plt>
    40060b:	bf ea 07 40 00       	mov    $0x4007ea,%edi
    400610:	e8 ab ff ff ff       	callq  4005c0 <puts@plt>
    400615:	bf f1 07 40 00       	mov    $0x4007f1,%edi
    40061a:	e8 a1 ff ff ff       	callq  4005c0 <puts@plt>
    40061f:	31 c0                	xor    %eax,%eax
    400621:	5b                   	pop    %rbx
    400622:	c3                   	retq