是否有 C++ 标准类在作用域退出时将变量设置为值 [英] Is there a C++ standard class to set a variable to a value at scope exit
问题描述
在成员函数的作用域内,我想临时将成员变量设置为某个值.
Within the scope of a member function, I want to temporarly set a member variable to a certain value.
然后,当这个函数返回时,我想把这个成员变量重置为一个给定的已知值.
Then, when this function returns, I want to reset this member variable to a given known value.
为了防止异常和多次返回,我已经用一个简单的 RAII 类来完成它.它是在成员函数的范围内定义的.
To bo safe against exceptions and multiple returns, and I've done it with a simple RAII like class. It's defined within the scope of the member function.
void MyClass::MyMemberFunction() {
struct SetBackToFalse {
SetBackToFalse(bool* p): m_p(p) {}
~SetBackToFalse() {*m_p=false;}
private:
bool* m_p;
};
m_theVariableToChange = true;
SetBackToFalse resetFalse( &m_theVariableToChange ); // Will reset the variable to false.
// Function body that may throw.
}
这显然很常见,我想知道 C++ 标准库中是否有这样的模板类这样做?
It seems so obviously commonplace, that I was wondering if there was any such template class doing this in the C++ standard library?
推荐答案
还没有(已经有提案).但是实现一个通用的已经很简单了;
Not yet (there have been proposals for this). But implementing a generic one is simple enough;
struct scope_exit {
std::function<void()> f_;
explicit scope_exit(std::function<void()> f) noexcept : f_(std::move(f)) {}
~scope_exit() { if (f_) f_(); }
};
// ...
m_theVariableToChange = true;
scope_exit resetFalse([&m_theVariableToChange]() { m_theVariableToChange = false; });
为简单起见,我对复制和移动构造函数等进行了编辑...
将它们标记为 = delete
将使上述解决方案成为最小的解决方案.更多;如果需要,可以允许移动,但应禁止复制.
Marking them as = delete
will make the above a minimal solution. Further; moving could be allowed if desired, but copying should be prohibited.
更完整的 scope_exit
看起来像(此处为在线演示);
A more complete scope_exit
would look like (online demo here);
template <typename F>
struct scope_exit {
F f_;
bool run_;
explicit scope_exit(F f) noexcept : f_(std::move(f)), run_(true) {}
scope_exit(scope_exit&& rhs) noexcept : f_((rhs.run_ = false, std::move(rhs.f_))), run_(true) {}
~scope_exit()
{
if (run_)
f_(); // RAII semantics apply, expected not to throw
}
// "in place" construction expected, no default ctor provided either
// also unclear what should be done with the old functor, should it
// be called since it is no longer needed, or not since *this is not
// going out of scope just yet...
scope_exit& operator=(scope_exit&& rhs) = delete;
// to be explicit...
scope_exit(scope_exit const&) = delete;
scope_exit& operator=(scope_exit const&) = delete;
};
template <typename F>
scope_exit<F> make_scope_exit(F&& f) noexcept
{
return scope_exit<F>{ std::forward<F>(f) };
}
实施注意事项;
std::function
可用于擦除函子的类型.std::function<void()>
根据所持有的函数的特定异常,为移动构造函数提供异常保证.此处- 这些异常规范与 C++ 提案和 GSL 实现一致
- 我已经编辑了
noexcept
的大部分动机,更多详细信息请参见 C++ 提案 - 析构函数的通常"RAII语义,因此范围退出"函数是适用的;它不会
throw
,这也与 C++11 规范关于析构函数的默认异常规范一致.请参阅 cppreference、SO Q&A,GotW#47 和 HIC++
std::function<void()>
can be used to erase the type of the functor.std::function<void()>
offers exception guarantees on the move constructors based on the exception specific of the held function. A sample of this implementation is found here- These exception specifications are consistent the C++ proposal and GSL implementations
- I've redacted most of the motivation for the
noexcept
, more substantial detail is found in the C++ proposal - The "usual" RAII semantics of the destructor, hence the "scope exit" function is applicable; it will not
throw
, this is also consistent with the C++11 specification on the default exception specification for a destructor. See cppreference, SO Q&A, GotW#47 and HIC++
可以找到其他实现;
- The C++ proposal mentioned above and its revision (as of this writing)
- Boost.ScopeExit
- The Microsoft GSL implementation
这篇关于是否有 C++ 标准类在作用域退出时将变量设置为值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!