Related
The Issue
I am currently working on a game. In this game,"game objects" of a certain type are stored in an std::vector. The Update (gameplay) code for these objects is executed on one thread, while rendering is handled by the main thread.
The vector of these "game objects" is passed by reference to the thread handling their Update code, so that the data is shared between threads. As such, some form of thread safety is required in order to prevent the render code from attempting to access memory that is being modified by the update code (which causes a crash).
Ideally, I would like to use a shared_mutex as part of these "game objects" stored within said vector. However, this won't compile and causes errors. My understanding is that this is because a mutex cannot be copied.
Is there a way to solve this problem that is performant, safe, and "not a nightmare to work with"?
The only viable solution I am seeing, is to prevent each specific type of object from updating and rendering at the same time. However, this would go some way to nullify the benefits of multithreading. I would estimate over 80% of game will be processing one singular type of object.
Basic Psuedocode to provide context below:
main(){
std::vector<Enemies> enemies;
std::thread(update_thread, std::ref(enemies), ... , ...);
while(true){
render_player();
render_enemies();
render_physics();
flip_to_display()
}
};
update_thread(std::vector<Enemies> &enemies, ... , ...){
while(true){
update_player();
update_enemies();
update_physics();
}
};
render_enemies(){
for(all enemies)
enemy.render();
}
update_enemies(){
for(all enemies)
enemy.update();
}
class Enemies{
//Would be nice to have the below, but afaik, not possible
std::shared_mutex mutex;
update(){
std::shared_lock<std::shared_mutex> lock(mutex);
//Write and Access data from enemy
}
render(){
std::shared_lock<std::shared_mutex> lock_shared(mutex);
//Only Access some data from enemy and draw it
}
}
NOTE:
I am using visual studio 2015, so I can only use C++14(ish) compatible features.
Based on the answers provided in the comments, I think my best option will be to find a more creative solution that sidesteps the issue entirely. In this case I will probably process ahead of time and write the results to a buffer. This way Rendering and Processing should by design avoid any conflicts, hence avoiding the need for lock conditions.
Providing I remember, this will most likely become the accepted solution (since the button can't be pressed for 2 days).
Working on a cpp project, where I need something like runtime event handler. My primary goal is to keep a track of various events that takes place in a sample program and based on the events specific handlers are triggered.
These event triggering handlers/functions are not contributing anything to the global objective of the sample program, but are just keeping track over various events in the cpp sample program.
My question is it prossible to create soemthing like custom eventhandlers in cpp?
If yes, is there any tutorial for creating such custom eventhandler?
eg:
Event are like failed to enter while loop. successfully entered while loop, created object, deleted object, changed global variable etc.
The simplest form of event handler is a registered callback function pointer:
enum Events {
FailedEnteringWhileLoop ,
SuccessfullyEnteredWhileLoop ,
};
typedef void(EventHandler*)(Events);
void MyEventHandler(Events ev) {
switch(ev) {
case FailedEnteringWhileLoop:
// Do something
break;
case SuccessfullyEnteredWhileLoop:
// Do something
break;
}
}
EventHandler evh = MyEventHandler;
bool whileLoopEntered = false;
while(condition) {
if(!whileLoopEntered) {
whileLoopEntered = true;
(*evh)(SuccessfullyEnteredWhileLoop);
}
}
if(!whileLoopEntered) {
(*evh)(FailedEnteringWhileLoop);
}
I am looking for events like failed to enter while loop. successfully
entered while loop, created object, deleted object, changed global
variable etc.
The C++ language itself does not track these kinds of things as "events". Generally speaking it doesn't provide hooks into any of the various fundamental activities that happen across code.
So to do what you're asking for requires building an infrastructure yourself and working it into your code in various ways. (Or finding someone else who has done the same sort of work already and made it available. Although you still would have to integrate it into your code.)
To give some idea of what might have to be done:
For creating and deleting objects you can override the new and delete operators. But that doesn't cover stack/local/etc objects. Otherwise you could wedge something the constructors and destructors of every class you want to track, or even have all of them derive from a common base class which encapsulates the tracking.
For changes to a variable, you would have to wrap that variable in a container which only exposes the ability to change it through member functions. Then those could be coded to raise events.
For entering loops... You're out of luck because a loop isn't an entity that can be extended or hooked. You literally have to put some kind of call at every loop you want to track.
As for the rest of the infrastructure, you would probably end up doing something like having all of those various "events" call to some kind of global logging object. If you need different things catch different events over the course of a program, then you might also need to build a way of registering and de-registering listeners (the listeners themselves being based on an interface to derive from or std::function or whatever suits your use case).
But in the end since there isn't an out-of-the-box way provided by the language, you might want to re-consider what you really want and what you hope to achieve with it. In fact you might be better off asking your question in terms how to accomplish the end goal you wanted this for rather than how to do this "event" system.
I am working on a large project in C++ that will have a graphical user interface.
The user interface will use some design pattern (MVVM/MVC) that will rely on the observer pattern.
My problem is that I currently have no way of predicting which parts of the Model should be observable. And there are many, many parts.
I find myself being pulled in several directions due to this issue:
If I develop back-end classes that do not support notification I will find myself violating the Open-Closed principle.
If I do provide support for notification to all Model classes and all of their data members it will have a massive performance cost that is unjustified since only a fraction of this support will actually be needed (even though this fraction is unknown).
The same is true if I only provide support for extension by making all non-const methods virtual and accessing these methods through base-pointers. This will also have a cost in readability.
I feel that out of these 3, (1.) is probably the lesser evil.
However, I feel like an ideal solution should actually exists in some language (definitely not C++), but I don't know if it's supported anywhere.
The unicorn solution I was thinking of is something like this:
Given a class Data, shouldn't it be possible for clients that seek to make Data observable do something like
#MakeObservable(Data)
as a compile time construct. This in turn would make it possible to call addObserver on Data objects and modify all assignments to data members with notifiers. it would also make you pay in performance only for what you get.
So my question is two-fold:
Am I right to assume that out of the 3 options I stated, (1.) is the lesser but necessary evil?
Does my unicorn solution exist anywhere? being worked on? or would be impossible to implement for some reason?
If I understand correctly, you're concerned with the cost of providing a signal/notification for potentially every observable property of every object.
Fortunately you're in luck, since storing a general thread-safe notifier with every single property of every object would generally be extremely expensive in any language or system.
Instead of getting all clever and trying to solve this problem at compile-time, which I recommend would shut out some very potentially useful options to a large-scale project (ex: plugins and scripting), I'd suggest thinking about how to make this cheaper at runtime. You want your signals to be stored at a coarser level than the individual properties of an object.
If you store just one with the object that passes along the appropriate data about which property was modified during a property change event to filter which clients to notify, then now we're getting a lot cheaper. We're exchanging some additional branching and larger aggregates for the connected slots, but you get a significantly smaller object in exchange with potentially faster read access, and I'd suggest this is a very valuable exchange in practice.
You can still design your public interface and even the event notification mechanism so that clients work with the system in a way that feels like they're connecting to properties rather than the whole object, perhaps even calling methods in a property (if it's an object/proxy) to connect slots if you need or can afford a back pointer to the object from a property.
If you're not sure, I would err on the side of attaching event slots to properties as well as modifying them as part of the object interface rather than property interface, as you'll have a lot more breathing room to optimize in exchange for a slightly different client aesthetic (one that I really don't think is less convenient so much as just 'different', or at least potentially worth the cost of eliminating a back pointer per property).
That's in the realm of convenience and wrapper-type things. But you don't need to violate the open-closed principle to achieve MVP designs in C++. Don't get crammed into a corner by data representation. You have a lot of flexibility at the public interface level.
Memory Compaction -- Paying for What We Use
On discovering that efficiency plays an important role here, I'd suggest some basic ways of thinking to help with that.
First, just because an object has some accessor like something() does not mean that the associated data has to be stored in that object. It doesn't even have to be stored anywhere until that method is called. If memory is your concern, it can be stored at some level outside.
Most software breaks down into hierarchies of aggregates owning resources. For example, in a 3D software, a vertex is owned by a mesh which is owned by the scene graph which is owned by the application root.
If you want designs where you pay almost no memory cost whatsoever for things that are not being used, then you want to associate the data to the object at a coarser level. If you store it directly in the object, then every object pays for what something() returns regardless of whether it is needed. If you store it indirectly in the object with a pointer, then you pay for the pointer to something() but not for the full cost of it unless it is used. If you associate it to the owner of the object, then retrieving it has a lookup cost, but one that is not as expensive as associating it to the owner of the owner of the object.
So there's always ways to get something very close to free for things you don't use if you associate at a coarse enough level. At granular levels you mitigate lookup and indirection overhead, at coarse levels you mitigate costs for things you don't use.
Massive Scale Events
Given massive scalability concerns with millions to billions of elements being processed, and still the desire for potentially some of them to generate events, if you can use an asynchronous design, I'd really recommend it here. You can have a lock-free per-thread event queue to which objects with a single bit flag set generate events. If the bit flag is not set, they don't.
This kind of deferred, async design is useful with such scale since it gives you periodic intervals (or possibly just other threads, though you'd need write locks -- as well as read locks, though writing is what needs to cheap -- in that case) in which to poll and devote full resources to bulk processing the queue while the more time-critical processing can continue without synchronizing with the event/notifier system.
Basic Example
// Interned strings are very useful here for fast lookups
// and reduced redundancy in memory.
// They're basically just indices or pointers to an
// associative string container (ex: hash or trie).
// Some contextual class for the thread storing things like a handle
// to its event queue, thread-local lock-free memory allocator,
// possible error codes triggered by functions called in the thread,
// etc. This is optional and can be replaced by thread-local storage
// or even just globals with an appropriate lock. However, while
// inconvenient, passing this down a thread's callstack is usually
// the most efficient and reliable, lock-free way.
// There may be times when passing around this contextual parameter
// is too impractical. There TLS helps in those exceptional cases.
class Context;
// Variant is some generic store/get/set anything type.
// A basic implementation is a void pointer combined with
// a type code to at least allow runtime checking prior to
// casting along with deep copying capabilities (functionality
// mapped to the type code). A more sophisticated one is
// abstract and overriden by subtypes like VariantInt
// or VariantT<int>
typedef void EventFunc(Context& ctx, int argc, Variant** argv);
// Your universal object interface. This is purely abstract:
// I recommend a two-tier design here:
// -- ObjectInterface->Object->YourSubType
// It'll give you room to use a different rep for
// certain subtypes without affecting ABI.
class ObjectInterface
{
public:
virtual ~Object() {}
// Leave it up to the subtype to choose the most
// efficient rep.
virtual bool has_events(Context& ctx) const = 0;
// Connect a slot to the object's signal (or its property
// if the event_id matches the property ID, e.g.).
// Returns a connection handle for th eslot. Note: RAII
// is useful here as failing to disconnect can have
// grave consequences if the slot is invalidated prior to
// the signal.
virtual int connect(Context& ctx, InternedString event_id, EventFunc func, const Variant& slot_data) = 0;
// Disconnect the slot from the signal.
virtual int disconnect(Context& ctx, int slot) = 0;
// Fetches a property with the specified ID O(n) integral cmps.
// Recommended: make properties stateless proxies pointing
// back to the object (more room for backend optimization).
// Properties can have set<T>/get<T> methods (can build this
// on top of your Variant if desired, but a bit more overhead
// if so).
// If even interned string compares are not fast enough for
// desired needs, then an alternative, less convenient interface
// to memoize property indices from an ID might be appropriate in
// addition to these.
virtual Property operator[](InternedString prop_id) = 0;
// Returns the nth property through an index.
virtual Property operator[](int n) = 0;
// Returns the number of properties for introspection/reflection.
virtual int num_properties() const = 0;
// Set the value of the specified property. This can generate
// an event with the matching property name to indicate that it
// changed.
virtual void set_value(Context& ctx, InternedString prop_id, const Variant& new_value) = 0;
// Returns the value of the specified property.
virtual const Variant& value(Context& ctx, InternedString prop_id) = 0;
// Poor man's RTTI. This can be ignored in favor of dynamic_cast
// for a COM-like design to retrieve additional interfaces the
// object supports if RTTI can be allowed for all builds/modes.
// I use this anyway for higher ABI compatibility with third
// parties.
virtual Interface* fetch_interface(Context& ctx, InternedString interface_id) = 0;
};
I'll avoid going into the nitty gritty details of the data representation -- the whole point is that it's flexible. What's important is to buy yourself room to change it as needed. Keeping the object abstract, keeping the property as a stateless proxy (with the exception of the backpointer to the object), etc. gives a lot of breathing room to profile and optimize away.
For async event handling, each thread should have a queue associated which can be passed down the call stack through this Context handle. When events occur, such as a property change, objects can push events to this queue through it if has_events() == true. Likewise, connect doesn't necessarily add any state to the object. It can create an associative structure, again through Context, which maps the object/event_id to the client. disconnect also removes it from that central thread source. Even the act of connecting/disconnecting a slot to/from a signal can be pushed to the event queue for a central, global place to process and make the appropriate associations (again preventing objects without observers from paying any memory cost).
When using this type of design, each thread should have at its entry point an exit handler for the thread which transfers the events pushed to the thread event queue from the thread-local queue to some global queue. This requires a lock but can be done not-too-frequently to avoid heavy contention and to allow each thread to not be slowed down by the event processing during performance-critical areas. Some kind of thread_yield kind of function should likewise be provided with such a design which also transfers from the thread-local queue to the global queue for long-lived threads/tasks.
The global queue is processed in a different thread, triggering the appropriate signals to the connected slots. There it can focus on bulk processing the queue when it isn't empty, sleeping/yielding when it is. The whole point of all of this is to aid performance: pushing to a queue is extremely cheap compared to the potential of sending synchronous events every time an object property is modified, and when working with massive scale inputs, this can be a very costly overhead. So simply pushing to a queue allows that thread to avoid spending its time on the event handling, deferring it to another thread.
Templatious library can help you with completely decoupling GUI and domain logic and making flexible/extendable/easy to maintain message systems and notifiers.
However, there's one downside - you need C++11 support for this.
Check out this article taming qt
And the example in github: DecoupledGuiExamples
So, you probably don't need notifiers on every class, you can just shoot messages from the inside functions and on specific classes where you can make any class send any message you want to GUI.
I am working on a project where I need to talk to a particular box over UDP. There will only ever be one box connected to the system at any given time. The connection should last the entire duration of the program.
I have written a class that works (yay!) in providing the necessary data to the hardware. However, my main problem is that now I have to account for the fact that someone (a programmer down the road who will more than likely just ignore all my very neat comments ;) ) may create more than one instance of this class. This will more than likely result in some hilarious and rather amusing crash where the hardware in question is wondering why it is receiving data from two sockets on the same machine. More troublesome is the fact that creating the object actually spawns a thread that periodically sends updates. So you can imagine if my imaginary future programmer does something like create a linked list of these objects (after all, this is C++ and we have the ability to do such things) the CPU might not be very happy after a while.
As a result, I turn to you... the more experienced people of SO who have seen such issues in the past. I have debated creating a singleton to handle all of this, but some of my readings lead me to believe that this might not be the way to go. There is a TON of information regarding them on the internet, and it's almost like asking a highly sensitive political question based on the responses I've seen.
An alternative I've developed that will preserve as much code as possible is to just use a static bool to keep track if there is an active thread passing data to the hardware. However, I suspect my approach can lead to race conditions in the case where I have competing threads attempting to access the class at the same time. Here's what I have thus far:
// in MyClass.cpp:
static bool running_ = false; // declared in the class in the .h, but defined here
MyClass::MyClass() {
// various initialization stuff you don't care about goes here
if (pthread_create(mythread_, NULL, MyThreadFunc, this) != 0) {
// error
}
else {
// no error
}
}
static void* MyClass::MyThreadFunc(void* args) {
MyClass myclass = static_cast<MyClass>(args);
// now I have access to all the stuff in MyClass
// do various checks here to make sure I can talk to the box
if (!running_) {
running_ = true;
// open a connection
while (!terminate) { // terminate is a flag set to true in the destructor
// update the hardware via UDP
}
// close the socket
running_ = false;
}
}
While I certainly note that this will check for only one instance being active, there is still the possibility that two concurrent threads will access the !running_ check at the same time and therefore both open the connection.
As a result, I'm wondering what my options are here? Do I implement a singleton? Is there a way I can get the static variable to work? Alternatively, do I just comment about this issue and hope that the next programmer understands to not open two instances to talk to the hardware?
As always, thanks for the help!
Edited to add:
I just had another idea pop into my mind... what if the static bool was a static lock instead? That way, I could set the lock and then just have subsequent instances attempt to get the lock and if they failed, just return a zombie class... Just a thought...
You're right, asking about singleton is likely to start a flamewar, that will not make you any wiser. You better make up your mind yourself. It's not that hard really if you are aware of the primary principles.
For your case I'd skip that whole branch as irrelevant, as your post is motivated by FEAR. Fear from a speculative issue. So let me just advise you on that: relax. You can't fight idiots. As soon as you invent some fool-proof schema, the universe evolves and will produce a better idiot that will go around it. Not worth the effort. Leave the idiot problem to the management and HR, to keep them employed elsewhere.
Your task is to provide working solution and proper documentation on how to use it (ideally with tests and examples too). If you document usage to create just a single instance of your stuff, and doing the listed init and teardown steps, you can just expext that as followed -- or if not it be the next guy's problem.
Most of the real life grief comes NOT from dismissing dox, but that dox not present or is inaccurate. So just do that part properly.
Once done, certainly nothing forbids you to ass a few static or runtime asserts on preconditions: it's not hard to count your class' instances and assert it will not go over 1.
What if you have two instances of the hardware itself? [I know you say it will only be one - but I've been there, done that on the aspect of "It's only ever going to be one!! Oh, <swearword>, now we need to use two..."].
Of course, your if(running_) is a race-condition. You really should use some sort of atomic type, so that you don't get two attempts to start the class at once. That also won't stop someone from trying to start two instances of the overall program.
Returning a zombie class seems like a BAD solution - throwing an exception, returning an error value, or some such would be a much better choice.
Would it be possible to have "the other side" control the number of connections? In other words, if a second instance tries to communicate, it gets an error back from the hardware that receives the message "Sorry, already have a connection"?
Sorry if this isn't really "an answer".
First, I do not think you can really protect anything from this imaginary future developer if he's so much into breaking your code. Comments/doc should do the trick. If he misses them, the hardware (or the code) will likely crash, and he will notice. Moreover, if he as a good reason to reuse your class (like connecting to some other hardwares of the same kind), you do not want to block him with nasty hidden tricks.
This said, for your example, I would consider using an atomic<bool> to avoid any concurrency issue, and use the compare_exchange member function instead of if(!running) running = true:
static std::atomic<bool> running;
...
bool expected = false;
if(running.compare_exchange_strong(expected, true)) {
...
I came across this article written by Andrei Alexandrescu and Petru Marginean many years ago, which presents and discusses a utility class called ScopeGuard for writing exception-safe code. I'd like to know if coding with these objects truly leads to better code or if it obfuscates error handling, in that perhaps the guard's callback would be better presented in a catch block? Does anyone have any experience using these in actual production code?
It definitely improves your code. Your tentatively formulated claim, that it's obscure and that code would merit from a catch block is simply not true in C++ because RAII is an established idiom. Resource handling in C++ is done by resource acquisition and garbage collection is done by implicit destructor calls.
On the other hand, explicit catch blocks would bloat the code and introduce subtle errors because the code flow gets much more complex and resource handling has to be done explicitly.
RAII (including ScopeGuards) isn't an obscure technique in C++ but firmly established best-practice.
Yes.
If there is one single piece of C++ code that I could recommend every C++ programmer spend 10 minutes learning, it is ScopeGuard (now part of the freely available Loki library).
I decided to try using a (slightly modified) version of ScopeGuard for a smallish Win32 GUI program I was working on. Win32 as you may know has many different types of resources that need to be closed in different ways (e.g. kernel handles are usually closed with CloseHandle(), GDI BeginPaint() needs to be paired with EndPaint(), etc.) I used ScopeGuard with all these resources, and also for allocating working buffers with new (e.g. for character set conversions to/from Unicode).
What amazed me was how much shorter the program was. Basically, it's a win-win: your code gets shorter and more robust at the same time. Future code changes can't leak anything. They just can't. How cool is that?
I often use it for guarding memory usage, things that need to be freed that were returned from the OS. For example:
DATA_BLOB blobIn, blobOut;
blobIn.pbData=const_cast<BYTE*>(data);
blobIn.cbData=length;
CryptUnprotectData(&blobIn, NULL, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobOut);
Guard guardBlob=guardFn(::LocalFree, blobOut.pbData);
// do stuff with blobOut.pbData
I think above answers lack one important note. As others have pointed out, you can use ScopeGuard in order to free allocated resources independent of failure (exception). But that might not be the only thing you might want to use scope guard for. In fact, the examples in linked article use ScopeGuard for a different purpose: transcations. In short, it might be useful if you have multiple objects (even if those objects properly use RAII) that you need to keep in a state that's somehow correlated. If change of state of any of those objects results in an exception (which, I presume, usually means that its state didn't change) then all changes already applied need to be rolled back. This creates it's own set of problems (what if a rollback fails as well?). You could try to roll out your own class that manages such correlated objects, but as the number of those increases it would get messy and you would probably fall back to using ScopeGuard internally anyway.
Yes.
It was so important in C++ that even a special syntax for it in D:
void somefunction() {
writeln("function enter");
// c++ has similar constructs but not in syntax level
scope(exit) writeln("function exit");
// do what ever you do, you never miss the function exit output
}
I haven't used this particular template but I've used something similar before. Yes, it does lead to clearer code when compared to equally robust code implemented in different ways.
I have to say, no, no it does not. The answers here help to demonstrate why it's a genuinely awful idea. Resource handling should be done through re-usable classes. The only thing they've achieved by using a scope guard is to violate DRY up the wazoo and duplicate their resource freeing code all over their codebase, instead of writing one class to handle the resource and then that's it, for the whole lot.
If scope guards have any actual uses, resource handling is not one of them. They're massively inferior to plain RAII in that case, since RAII is deduplicated and automatic and scope guards are manual code duplication or bust.
My experience shows that usage of scoped_guard is far inferior to any of the short reusable RAII classes that you can write by hand.
Before trying the scoped_guard, I had written RAII classes to
set GLcolor or GLwidth back to the original, once I've drawn a shape
make sure a file has fclosed once I had fopened it.
reset a mouse pointer to its initial state, after I've changed it to gears/hourgrlass during a execution of a slow function
reset the sorting state of a QListView's back to its previous state, once I've temporarily finished with altering its QListViewItems -- I did not want the list to reorder itself everytime I changed the text of a single item...
using simple RAII class
Here's how my code looked like with my hand-crafted RAII classes:
class scoped_width {
int m_old_width;
public:
scoped_width(int w) {
m_old_width = getGLwidth();
setGLwidth(w);
}
~scoped_width() {
setGLwidth(m_old_width);
}
};
void DrawTriangle(Tria *t)
{
// GLwidth=1 here
auto guard = scoped_width(2); // sets GLwidth=2
draw_line(t->a, t->b);
draw_line(t->b, t->c);
draw_line(t->c, t->a);
setGLwidth(5);
draw_point(t->a);
draw_point(t->b);
draw_point(t->c);
} // scoped_width sets GLwidth back to 1 here
Very simple implementation for scoped_width, and quite reusable.
Very simple and readable from the consumer side, also.
using scoped_guard (C++14)
Now, with the scoped_guard, I have to capture the existing value in the introducer ([]) in order to pass it to the guard's callback:
void DrawTriangle(Tria *t)
{
// GLwidth=1 here
auto guard = sg::make_scoped_guard([w=getGLwidth()](){ setGLwidth(w); }); // capture current GLwidth in order to set it back
setGLwidth(2); // sets GLwidth=2
draw_line(t->a, t->b);
draw_line(t->b, t->c);
draw_line(t->c, t->a);
setGLwidth(5);
draw_point(t->a);
draw_point(t->b);
draw_point(t->c);
} // scoped_guard sets GLwidth back to 1 here
The above doesn't even work on C++11.
Not to mention that trying to introduce the state to the lambda this way hurts my eyes.
using scoped_guard (C++11)
In C++11 you have to do this:
void DrawTriangle(Tria *t)
{
// GLwidth=1 here
int previous_width = getGLwidth(); // explicitly capture current width
auto guard = sg::make_scoped_guard([=](){ setGLwidth(previous_width); }); // pass it to lambda in order to set it back
setGLwidth(2); // sets GLwidth=2
draw_line(t->a, t->b);
draw_line(t->b, t->c);
draw_line(t->c, t->a);
setGLwidth(5);
draw_point(t->a);
draw_point(t->b);
draw_point(t->c);
} // scoped_guard sets GLwidth back to 1 here
As you can see,
the scoped_guard snoppet requires
3 lines to keep previous value (state) and set it to a new one, and
2 stack variables (previous_width and guard, again) to hold the previous state
the hand-crafted RAII class requires
1 readable line to set new state and keep the previous one, and
1 stack variable (guard) to hold the previous state.
Conclusion
I think that examples such as
void some_function() {
sg::scoped_guard([](){ cout << "this is printed last"; }
cout << "this is printed first";
}
are no proof of the usefullness of scoped_guard.
I hope that somebody can show me why I don't get the expected gain from scoped_guard.
I am convinced that RAII can be exploited better by writing short hand-crafted classes, than using the more generic but hard to use scoped_guard