Where can I find a good Scope Guard implementation for my C++ projects?
Asked Answered
H

7

18

I just recently learned about Scope Guard C++ idiom. Unfortunately I can't find any good implementation of it.

Can anyone point me to some good and usable Scope Guard implementation in C++?

Thanks, Boda Cydo.

Hypertension answered 12/8, 2010 at 11:56 Comment(7)
Never heard of this before - for others lie me, see en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Scope_Guard. It seems unlikely to be very useful, IMHO. And it is trivial to implement - you don't need to "find an implementation".Your
@Neil: interesting like as it's widely different from what I would expect from a RAII related idiom. I do wonder who handles the resource after successful execution.Bunker
@Matthieu Me too. I can't see what this has over smart pointers, except for the additional possibilities for screw-ups.Your
Smart pointer as far as I understand only does delete but with scope guards you can also delete [] or free or fclose() or close_my_object, etc. So I think it's better. Please correct me if I am wrong.Hypertension
Smart pointers don't have to only call delete. See boost.org/doc/libs/1_43_0/libs/smart_ptr/…. Although I personally think a Scope Guard is clearer for cases like close_my_object.Deficit
I really recommend Boost's Scope Exit, they did a good job on it.Italic
If you can use C++11, you can use std::shared_ptr and std::unique_ptr which are accessible via #include <memory>. This comment is an update, because I realized that C++11 was not available when the question was first posted.Perish
I
8

ScopeGuard has been included in the Loki library (advertised in Modern C++ Design by Andrei Alexandrescu, I'm sure you've heard of this great book), and is mature enough to be used in production code, imo.

Just to be clear: We're talking about writing exception safe code using RAII.

Additional reading (on StackOverflow): Does ScopeGuard use really lead to better code?

Investiture answered 12/8, 2010 at 12:3 Comment(4)
Yes, I have heard about Modern C++ Design. But I have not read this book because it's very hard to understand! I maybe understand one sentence in ever page. :)Hypertension
@boda Actually, I think it is rather clearly written. I think the problem is that he doesn't always make totally explicit the motivations for doing what he is talking about, but expects you to know them.Your
I found Modern C++ design hard at first but after reading a tutorial on Haskell and re reading stuff on templates I understood it well and in retrospect I don't know what he should have done differently. Keep coming back to it, it is a really good bookFoetation
A new, C++11-ish ScopeGuard by Alexandrescu is now part of folly, see this answer by @MikeEllery.Weinberger
D
15

The original ScopeGuard class is included in this Dr. Dobb's article by Andrei Alexandrescu and Petru Marginean. A slightly improved version, with some changes from Joshua Lehrer is available here. (Lehrer's version is the one that I'm using in my projects.) It's also included in the Loki library.

Boost now has a ScopeExit library that's more powerful than ScopeGuard (since it can execute arbitrary code, whereas ScopeGuard can only call a single preexisting function).

Edit: With all of that said, a Scope Guard is really just a specific application of RAII, so you really ought to at least understand the concept of how to implement one.

Deficit answered 12/8, 2010 at 17:12 Comment(1)
Since this answer was written, C++11 came out, and after it - a new ScopeGuard, much nicer than before; consider deprecating your answer in favor of this one by @MikeEllery.Weinberger
I
8

ScopeGuard has been included in the Loki library (advertised in Modern C++ Design by Andrei Alexandrescu, I'm sure you've heard of this great book), and is mature enough to be used in production code, imo.

Just to be clear: We're talking about writing exception safe code using RAII.

Additional reading (on StackOverflow): Does ScopeGuard use really lead to better code?

Investiture answered 12/8, 2010 at 12:3 Comment(4)
Yes, I have heard about Modern C++ Design. But I have not read this book because it's very hard to understand! I maybe understand one sentence in ever page. :)Hypertension
@boda Actually, I think it is rather clearly written. I think the problem is that he doesn't always make totally explicit the motivations for doing what he is talking about, but expects you to know them.Your
I found Modern C++ design hard at first but after reading a tutorial on Haskell and re reading stuff on templates I understood it well and in retrospect I don't know what he should have done differently. Keep coming back to it, it is a really good bookFoetation
A new, C++11-ish ScopeGuard by Alexandrescu is now part of folly, see this answer by @MikeEllery.Weinberger
S
4

The Folly library (open-source from facebook) also provides an implementation (not surprising since A.A. is employed by them):

https://github.com/facebook/folly/blob/master/folly/ScopeGuard.h

I think this and the MNMLSTC implementation mentioned here are both worth consideration.

Sadiras answered 4/6, 2015 at 19:3 Comment(0)
F
1

Let me offer a basic C++20 version.

#include <concepts>
#include <type_traits>

template <std::invocable Cleanup>
class [[nodiscard]] scope_guard
{
    Cleanup d;
public:
    scope_guard(Cleanup&& d) : d{std::forward<Cleanup>(d)} {}
    scope_guard(const scope_guard&) = delete;

    ~scope_guard(){d();}
};

// allow construction from plain function
template <typename F>
scope_guard(F&&) -> scope_guard<std::decay_t<F>>;

Please note that unless we need to move the scope_guard around, it adds zero memory overhead over Cleanup callable, because we don't need to hold it in a resettable manner, because we don't need move constructor, because we got class template argument deduction.

A fine example of how expressive the language became. Thank you commitee!

Footlights answered 3/3, 2021 at 19:25 Comment(0)
M
0

A "Scope Guard" object is just one instance of the much broader RAII idiom.

And there is no single implementation of that. It is something a C++ programmer has to understand, not just copy/paste. Luckily, it is also pretty trivial to implement.

You create a class which represents some kind of resource. When the class is instantiated (by one of its constructors), it should acquire the resource, and throw an exception if that fails. When the class is destroyed, it should dispose of the resource, performing all the necessary cleanup.

And... that's it. You also have to handle copy constructor and assignment operator (either by cloning the resource or by making these two functions private so they're never called).

You don't need to find "a good implementation", because you're going to write dozens and dozens of different implementations yourself. They're trivial to write, and they can't easily be reused because each one wraps a different type of resource.

Monofilament answered 12/8, 2010 at 12:11 Comment(2)
Thanks, jalf, I will try to write my own. Boy, is this going to be a difficult exercise for me. I have never even dreamed of writing such complex code!Hypertension
The advantage of a good Scope Guard class is that it makes it easy to call arbitrary code at cleanup, without having to write dozens and dozens of different implementations yourself.Deficit
R
0

There's a proposal to add scope_guard to the standard library. You can read the paper, which includes a sample implementation you can copy/paste, here. See section 9.1 for the implementation.

Rickart answered 3/5, 2014 at 2:10 Comment(0)
G
0

MNMLSTC core has a modern C++11 implementation of the scope guard idiom.

Gaona answered 14/8, 2014 at 8:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.