One Minute to C++ "defer"

1
2
3
4
5
6
7
template<typename Lambda>
struct Defer : Lambda {
~Defer() { Lambda::operator()(); }
};

template<typename Lambda>
Defer(Lambda) -> Defer<Lambda>;
1
2
3
4
// usage
Defer guard{[sockfd]{
shutdown(sockfd, SHUT_WR);
}};

This is a short tutorial on implementing golang-style "defer" in C++.

1
2
3
The favored technique will be:
+ C++ template and lambda
- C macro

The Explaination

  1. Inheriting from a lambda type, we define a template class Defer whose dtor calls the Lambda::operator().
  2. Explicitly deduce a ctor Defer(Lambda) to the exact type Defer<Lambda>. This step can be omitted in C++20 or later.
  3. Define a Defer object, initialized with the lambda, at any scope, similar to golang.

Tips and More

  1. You may need to capture some local variables into the lambda.
  2. -O1 is recommended for the lambda inlining, which makes this idiom zero-overhead.
  3. Using C macro, this idiom can be developed more concise. Personally I don't like C macro, however, because of safety concerns.
  4. A library: lizho/FakeGolang