What's the shortest path in C++11 (or newer) to create an RAII wrapper without having to write a new class?
Often I'm in a situation where I need a simple RAII wrapper, but I wouldn't want to create a whole new class for this for many reasons including time constraints and organization problems. My quick-n-dirty solution is the following.
Say I want to make sure that by the end of the scope, I want a boolean to switch back to its original state:
bool prevState = currState;
currState = newState;
std::unique_ptr<int, std::function<void(int*)>> txEnder(new int(0), [&prevState](int* p) {
currState = prevState;
delete p;
});
This solution works fine, but the dirty part is the necessity to allocate and deallocate that integer just to make unique_ptr
work and call the custom destructor at destruction.
Is there a cleaner way to do this without having to write a whole class, and get rid of the new
for the dummy int
?
c++ c++11 c++14 c++17 raii
|
show 9 more comments
Often I'm in a situation where I need a simple RAII wrapper, but I wouldn't want to create a whole new class for this for many reasons including time constraints and organization problems. My quick-n-dirty solution is the following.
Say I want to make sure that by the end of the scope, I want a boolean to switch back to its original state:
bool prevState = currState;
currState = newState;
std::unique_ptr<int, std::function<void(int*)>> txEnder(new int(0), [&prevState](int* p) {
currState = prevState;
delete p;
});
This solution works fine, but the dirty part is the necessity to allocate and deallocate that integer just to make unique_ptr
work and call the custom destructor at destruction.
Is there a cleaner way to do this without having to write a whole class, and get rid of the new
for the dummy int
?
c++ c++11 c++14 c++17 raii
1
Not sure you need to allocate anything?
– Matthieu Brucher
Dec 12 '18 at 9:37
2
What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
– πάντα ῥεῖ
Dec 12 '18 at 9:41
1
@TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
– πάντα ῥεῖ
Dec 12 '18 at 9:44
1
@πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
– The Quantum Physicist
Dec 12 '18 at 9:45
1
@TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
– πάντα ῥεῖ
Dec 12 '18 at 9:48
|
show 9 more comments
Often I'm in a situation where I need a simple RAII wrapper, but I wouldn't want to create a whole new class for this for many reasons including time constraints and organization problems. My quick-n-dirty solution is the following.
Say I want to make sure that by the end of the scope, I want a boolean to switch back to its original state:
bool prevState = currState;
currState = newState;
std::unique_ptr<int, std::function<void(int*)>> txEnder(new int(0), [&prevState](int* p) {
currState = prevState;
delete p;
});
This solution works fine, but the dirty part is the necessity to allocate and deallocate that integer just to make unique_ptr
work and call the custom destructor at destruction.
Is there a cleaner way to do this without having to write a whole class, and get rid of the new
for the dummy int
?
c++ c++11 c++14 c++17 raii
Often I'm in a situation where I need a simple RAII wrapper, but I wouldn't want to create a whole new class for this for many reasons including time constraints and organization problems. My quick-n-dirty solution is the following.
Say I want to make sure that by the end of the scope, I want a boolean to switch back to its original state:
bool prevState = currState;
currState = newState;
std::unique_ptr<int, std::function<void(int*)>> txEnder(new int(0), [&prevState](int* p) {
currState = prevState;
delete p;
});
This solution works fine, but the dirty part is the necessity to allocate and deallocate that integer just to make unique_ptr
work and call the custom destructor at destruction.
Is there a cleaner way to do this without having to write a whole class, and get rid of the new
for the dummy int
?
c++ c++11 c++14 c++17 raii
c++ c++11 c++14 c++17 raii
edited Dec 12 '18 at 10:01
πάντα ῥεῖ
71.8k972134
71.8k972134
asked Dec 12 '18 at 9:35
The Quantum Physicist
11.4k64596
11.4k64596
1
Not sure you need to allocate anything?
– Matthieu Brucher
Dec 12 '18 at 9:37
2
What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
– πάντα ῥεῖ
Dec 12 '18 at 9:41
1
@TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
– πάντα ῥεῖ
Dec 12 '18 at 9:44
1
@πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
– The Quantum Physicist
Dec 12 '18 at 9:45
1
@TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
– πάντα ῥεῖ
Dec 12 '18 at 9:48
|
show 9 more comments
1
Not sure you need to allocate anything?
– Matthieu Brucher
Dec 12 '18 at 9:37
2
What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
– πάντα ῥεῖ
Dec 12 '18 at 9:41
1
@TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
– πάντα ῥεῖ
Dec 12 '18 at 9:44
1
@πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
– The Quantum Physicist
Dec 12 '18 at 9:45
1
@TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
– πάντα ῥεῖ
Dec 12 '18 at 9:48
1
1
Not sure you need to allocate anything?
– Matthieu Brucher
Dec 12 '18 at 9:37
Not sure you need to allocate anything?
– Matthieu Brucher
Dec 12 '18 at 9:37
2
2
What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
– πάντα ῥεῖ
Dec 12 '18 at 9:41
What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
– πάντα ῥεῖ
Dec 12 '18 at 9:41
1
1
@TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
– πάντα ῥεῖ
Dec 12 '18 at 9:44
@TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
– πάντα ῥεῖ
Dec 12 '18 at 9:44
1
1
@πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
– The Quantum Physicist
Dec 12 '18 at 9:45
@πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
– The Quantum Physicist
Dec 12 '18 at 9:45
1
1
@TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
– πάντα ῥεῖ
Dec 12 '18 at 9:48
@TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
– πάντα ῥεῖ
Dec 12 '18 at 9:48
|
show 9 more comments
4 Answers
4
active
oldest
votes
A little bit better than yours: You can use &prevState
in the custom destructor without deleting it, so you do not need to new
and delete
something:
void foo(bool & currState, bool newState)
{
bool prevState = currState;
currState = newState;
std::unique_ptr<bool, std::function<void(bool*)>> txEnder(&prevState, [&prevState, &currState](bool* p) {
currState = prevState;
});
cout << "currState: " << currState << endl;
}
You also forgot to capture currState
in the lambda.
Here is an example: https://ideone.com/DH7vZu
This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
– The Quantum Physicist
Dec 12 '18 at 9:53
Interesting solution for the problem.
– πάντα ῥεῖ
Dec 12 '18 at 9:59
1
I would just note that this solution might not be the most efficient one, sincestd::function
applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
– Daniel Langr
Dec 12 '18 at 10:11
1
@TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...
) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
– Daniel Langr
Dec 12 '18 at 11:57
1
@DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
– The Quantum Physicist
Dec 12 '18 at 12:12
|
show 6 more comments
You can use BOOST_SCOPE_EXIT
auto prevState{currState};
currState = newState;
BOOST_SCOPE_EXIT(&currState, &prevState)
{
currState = prevState;
} BOOST_SCOPE_EXIT_END
2
Yay. Boost. :-/
– Johannes Overmann
Dec 12 '18 at 23:16
add a comment |
Don't use std::function
. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz
If you absolutely don't want to use any external class or function, do below:
bool foo_2() {
bool f = false;
auto eos = [&](void*){
f = true;
};
std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
return f;
}
If you are ok with a little reusable function, below works. This abstracts the unused void*
.
C++14 or later
template<class F>
auto call_at_end_of_scope(F&& f){
auto eos = [f{std::forward<F>(f)}](void*){f();};
return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
}
bool foo_3() {
bool f = false;
auto handle = call_at_end_of_scope([&](){
f = true;
});
return f;
}
add a comment |
How about gsl::finally
? Library is not so heavy as boost and finally
does not use std::function
, so can be easly inlined. Also no dynamic allocation of std::unique_ptr
using namespace std;
void foo(bool & currState, bool newState)
{
auto revertState = gsl::finally([prevState = currState, &currState]{
currState = prevState;
});
currState = newState;
cout << "currState: " << currState << endl;
}
int main() {
bool state = false;
foo(state, true);
cout << "state: " << state << endl;
return 0;
}
Online example: https://ideone.com/Xi1izz (with copied gsl::finally
, since #include <gsl/gsl>
is not available here)
Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
– The Quantum Physicist
Dec 15 '18 at 11:46
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53739994%2fwhats-the-shortest-path-in-c11-or-newer-to-create-an-raii-wrapper-without-h%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
A little bit better than yours: You can use &prevState
in the custom destructor without deleting it, so you do not need to new
and delete
something:
void foo(bool & currState, bool newState)
{
bool prevState = currState;
currState = newState;
std::unique_ptr<bool, std::function<void(bool*)>> txEnder(&prevState, [&prevState, &currState](bool* p) {
currState = prevState;
});
cout << "currState: " << currState << endl;
}
You also forgot to capture currState
in the lambda.
Here is an example: https://ideone.com/DH7vZu
This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
– The Quantum Physicist
Dec 12 '18 at 9:53
Interesting solution for the problem.
– πάντα ῥεῖ
Dec 12 '18 at 9:59
1
I would just note that this solution might not be the most efficient one, sincestd::function
applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
– Daniel Langr
Dec 12 '18 at 10:11
1
@TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...
) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
– Daniel Langr
Dec 12 '18 at 11:57
1
@DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
– The Quantum Physicist
Dec 12 '18 at 12:12
|
show 6 more comments
A little bit better than yours: You can use &prevState
in the custom destructor without deleting it, so you do not need to new
and delete
something:
void foo(bool & currState, bool newState)
{
bool prevState = currState;
currState = newState;
std::unique_ptr<bool, std::function<void(bool*)>> txEnder(&prevState, [&prevState, &currState](bool* p) {
currState = prevState;
});
cout << "currState: " << currState << endl;
}
You also forgot to capture currState
in the lambda.
Here is an example: https://ideone.com/DH7vZu
This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
– The Quantum Physicist
Dec 12 '18 at 9:53
Interesting solution for the problem.
– πάντα ῥεῖ
Dec 12 '18 at 9:59
1
I would just note that this solution might not be the most efficient one, sincestd::function
applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
– Daniel Langr
Dec 12 '18 at 10:11
1
@TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...
) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
– Daniel Langr
Dec 12 '18 at 11:57
1
@DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
– The Quantum Physicist
Dec 12 '18 at 12:12
|
show 6 more comments
A little bit better than yours: You can use &prevState
in the custom destructor without deleting it, so you do not need to new
and delete
something:
void foo(bool & currState, bool newState)
{
bool prevState = currState;
currState = newState;
std::unique_ptr<bool, std::function<void(bool*)>> txEnder(&prevState, [&prevState, &currState](bool* p) {
currState = prevState;
});
cout << "currState: " << currState << endl;
}
You also forgot to capture currState
in the lambda.
Here is an example: https://ideone.com/DH7vZu
A little bit better than yours: You can use &prevState
in the custom destructor without deleting it, so you do not need to new
and delete
something:
void foo(bool & currState, bool newState)
{
bool prevState = currState;
currState = newState;
std::unique_ptr<bool, std::function<void(bool*)>> txEnder(&prevState, [&prevState, &currState](bool* p) {
currState = prevState;
});
cout << "currState: " << currState << endl;
}
You also forgot to capture currState
in the lambda.
Here is an example: https://ideone.com/DH7vZu
answered Dec 12 '18 at 9:45
mch
5,12921632
5,12921632
This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
– The Quantum Physicist
Dec 12 '18 at 9:53
Interesting solution for the problem.
– πάντα ῥεῖ
Dec 12 '18 at 9:59
1
I would just note that this solution might not be the most efficient one, sincestd::function
applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
– Daniel Langr
Dec 12 '18 at 10:11
1
@TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...
) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
– Daniel Langr
Dec 12 '18 at 11:57
1
@DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
– The Quantum Physicist
Dec 12 '18 at 12:12
|
show 6 more comments
This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
– The Quantum Physicist
Dec 12 '18 at 9:53
Interesting solution for the problem.
– πάντα ῥεῖ
Dec 12 '18 at 9:59
1
I would just note that this solution might not be the most efficient one, sincestd::function
applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.
– Daniel Langr
Dec 12 '18 at 10:11
1
@TheQuantumPhysicist Also note that there is a proposal for adding scope guards (std::scope_...
) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.
– Daniel Langr
Dec 12 '18 at 11:57
1
@DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
– The Quantum Physicist
Dec 12 '18 at 12:12
This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
– The Quantum Physicist
Dec 12 '18 at 9:53
This is perfect. I don't know how this didn't occur to me. I'm just being a little paranoid thinking whether this breaks any rules!
– The Quantum Physicist
Dec 12 '18 at 9:53
Interesting solution for the problem.
– πάντα ῥεῖ
Dec 12 '18 at 9:59
Interesting solution for the problem.
– πάντα ῥεῖ
Dec 12 '18 at 9:59
1
1
I would just note that this solution might not be the most efficient one, since
std::function
applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.– Daniel Langr
Dec 12 '18 at 10:11
I would just note that this solution might not be the most efficient one, since
std::function
applies type erasure, which implies dynamic memory allocations (possibly small-buffer optimized) and virtual function overhead (see, e.g., stackoverflow.com/a/9088690/580083). "Classic" ScopeGuard, such as that from Boost, might be more efficient.– Daniel Langr
Dec 12 '18 at 10:11
1
1
@TheQuantumPhysicist Also note that there is a proposal for adding scope guards (
std::scope_...
) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.– Daniel Langr
Dec 12 '18 at 11:57
@TheQuantumPhysicist Also note that there is a proposal for adding scope guards (
std::scope_...
) into the Stadndard library: open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0052r9.pdf.– Daniel Langr
Dec 12 '18 at 11:57
1
1
@DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
– The Quantum Physicist
Dec 12 '18 at 12:12
@DanielLangr I would appreciate it more if they add destructors to lamdas... that would be a killer feature!
– The Quantum Physicist
Dec 12 '18 at 12:12
|
show 6 more comments
You can use BOOST_SCOPE_EXIT
auto prevState{currState};
currState = newState;
BOOST_SCOPE_EXIT(&currState, &prevState)
{
currState = prevState;
} BOOST_SCOPE_EXIT_END
2
Yay. Boost. :-/
– Johannes Overmann
Dec 12 '18 at 23:16
add a comment |
You can use BOOST_SCOPE_EXIT
auto prevState{currState};
currState = newState;
BOOST_SCOPE_EXIT(&currState, &prevState)
{
currState = prevState;
} BOOST_SCOPE_EXIT_END
2
Yay. Boost. :-/
– Johannes Overmann
Dec 12 '18 at 23:16
add a comment |
You can use BOOST_SCOPE_EXIT
auto prevState{currState};
currState = newState;
BOOST_SCOPE_EXIT(&currState, &prevState)
{
currState = prevState;
} BOOST_SCOPE_EXIT_END
You can use BOOST_SCOPE_EXIT
auto prevState{currState};
currState = newState;
BOOST_SCOPE_EXIT(&currState, &prevState)
{
currState = prevState;
} BOOST_SCOPE_EXIT_END
answered Dec 12 '18 at 9:41
VTT
23.8k42345
23.8k42345
2
Yay. Boost. :-/
– Johannes Overmann
Dec 12 '18 at 23:16
add a comment |
2
Yay. Boost. :-/
– Johannes Overmann
Dec 12 '18 at 23:16
2
2
Yay. Boost. :-/
– Johannes Overmann
Dec 12 '18 at 23:16
Yay. Boost. :-/
– Johannes Overmann
Dec 12 '18 at 23:16
add a comment |
Don't use std::function
. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz
If you absolutely don't want to use any external class or function, do below:
bool foo_2() {
bool f = false;
auto eos = [&](void*){
f = true;
};
std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
return f;
}
If you are ok with a little reusable function, below works. This abstracts the unused void*
.
C++14 or later
template<class F>
auto call_at_end_of_scope(F&& f){
auto eos = [f{std::forward<F>(f)}](void*){f();};
return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
}
bool foo_3() {
bool f = false;
auto handle = call_at_end_of_scope([&](){
f = true;
});
return f;
}
add a comment |
Don't use std::function
. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz
If you absolutely don't want to use any external class or function, do below:
bool foo_2() {
bool f = false;
auto eos = [&](void*){
f = true;
};
std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
return f;
}
If you are ok with a little reusable function, below works. This abstracts the unused void*
.
C++14 or later
template<class F>
auto call_at_end_of_scope(F&& f){
auto eos = [f{std::forward<F>(f)}](void*){f();};
return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
}
bool foo_3() {
bool f = false;
auto handle = call_at_end_of_scope([&](){
f = true;
});
return f;
}
add a comment |
Don't use std::function
. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz
If you absolutely don't want to use any external class or function, do below:
bool foo_2() {
bool f = false;
auto eos = [&](void*){
f = true;
};
std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
return f;
}
If you are ok with a little reusable function, below works. This abstracts the unused void*
.
C++14 or later
template<class F>
auto call_at_end_of_scope(F&& f){
auto eos = [f{std::forward<F>(f)}](void*){f();};
return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
}
bool foo_3() {
bool f = false;
auto handle = call_at_end_of_scope([&](){
f = true;
});
return f;
}
Don't use std::function
. It creates a lot of code including vtables. https://gcc.godbolt.org/z/XgDoHz
If you absolutely don't want to use any external class or function, do below:
bool foo_2() {
bool f = false;
auto eos = [&](void*){
f = true;
};
std::unique_ptr<void, decltype(eos)> h{&eos,std::move(eos)};
return f;
}
If you are ok with a little reusable function, below works. This abstracts the unused void*
.
C++14 or later
template<class F>
auto call_at_end_of_scope(F&& f){
auto eos = [f{std::forward<F>(f)}](void*){f();};
return std::unique_ptr<void, decltype(eos)>{&eos,std::move(eos)};
}
bool foo_3() {
bool f = false;
auto handle = call_at_end_of_scope([&](){
f = true;
});
return f;
}
edited Dec 12 '18 at 15:27
answered Dec 12 '18 at 11:38
balki
11k1760107
11k1760107
add a comment |
add a comment |
How about gsl::finally
? Library is not so heavy as boost and finally
does not use std::function
, so can be easly inlined. Also no dynamic allocation of std::unique_ptr
using namespace std;
void foo(bool & currState, bool newState)
{
auto revertState = gsl::finally([prevState = currState, &currState]{
currState = prevState;
});
currState = newState;
cout << "currState: " << currState << endl;
}
int main() {
bool state = false;
foo(state, true);
cout << "state: " << state << endl;
return 0;
}
Online example: https://ideone.com/Xi1izz (with copied gsl::finally
, since #include <gsl/gsl>
is not available here)
Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
– The Quantum Physicist
Dec 15 '18 at 11:46
add a comment |
How about gsl::finally
? Library is not so heavy as boost and finally
does not use std::function
, so can be easly inlined. Also no dynamic allocation of std::unique_ptr
using namespace std;
void foo(bool & currState, bool newState)
{
auto revertState = gsl::finally([prevState = currState, &currState]{
currState = prevState;
});
currState = newState;
cout << "currState: " << currState << endl;
}
int main() {
bool state = false;
foo(state, true);
cout << "state: " << state << endl;
return 0;
}
Online example: https://ideone.com/Xi1izz (with copied gsl::finally
, since #include <gsl/gsl>
is not available here)
Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
– The Quantum Physicist
Dec 15 '18 at 11:46
add a comment |
How about gsl::finally
? Library is not so heavy as boost and finally
does not use std::function
, so can be easly inlined. Also no dynamic allocation of std::unique_ptr
using namespace std;
void foo(bool & currState, bool newState)
{
auto revertState = gsl::finally([prevState = currState, &currState]{
currState = prevState;
});
currState = newState;
cout << "currState: " << currState << endl;
}
int main() {
bool state = false;
foo(state, true);
cout << "state: " << state << endl;
return 0;
}
Online example: https://ideone.com/Xi1izz (with copied gsl::finally
, since #include <gsl/gsl>
is not available here)
How about gsl::finally
? Library is not so heavy as boost and finally
does not use std::function
, so can be easly inlined. Also no dynamic allocation of std::unique_ptr
using namespace std;
void foo(bool & currState, bool newState)
{
auto revertState = gsl::finally([prevState = currState, &currState]{
currState = prevState;
});
currState = newState;
cout << "currState: " << currState << endl;
}
int main() {
bool state = false;
foo(state, true);
cout << "state: " << state << endl;
return 0;
}
Online example: https://ideone.com/Xi1izz (with copied gsl::finally
, since #include <gsl/gsl>
is not available here)
answered Dec 15 '18 at 11:09
R2RT
957511
957511
Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
– The Quantum Physicist
Dec 15 '18 at 11:46
add a comment |
Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
– The Quantum Physicist
Dec 15 '18 at 11:46
Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
– The Quantum Physicist
Dec 15 '18 at 11:46
Your solution may be correct, but the challenge was to have the shortest path. The answer that is accepted is super-short and doesn't have any dynamic allocation.
– The Quantum Physicist
Dec 15 '18 at 11:46
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53739994%2fwhats-the-shortest-path-in-c11-or-newer-to-create-an-raii-wrapper-without-h%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Not sure you need to allocate anything?
– Matthieu Brucher
Dec 12 '18 at 9:37
2
What about writing a simple class once and give it a lambda as you want at construction and call that at the destructor? Similar like a lock guard.
– πάντα ῥεῖ
Dec 12 '18 at 9:41
1
@TheQuantumPhysicist I am not talking about new classes (<- plural), just a single one you can use for all of these cases. It would be very simple, and you even can make it a template if you need to have stuff forwarded to the lambda.
– πάντα ῥεῖ
Dec 12 '18 at 9:44
1
@πάνταῥεῖ I know, buddy. I have one that I discussed before on Stackoverflow (I call SmartHandle). But, again, I don't have the freedom to do that in all the projects I work at depending on many circumstances, ranging from hastiness down to project organization problems.
– The Quantum Physicist
Dec 12 '18 at 9:45
1
@TheQuantumPhysicist What a pity if you can't do the necessary work because of such silly circumstances. But I know that kind of situation.
– πάντα ῥεῖ
Dec 12 '18 at 9:48