是否有 C++ 标准类在作用域退出时将变量设置为值 [英] Is there a C++ standard class to set a variable to a value at scope exit

查看:70
本文介绍了是否有 C++ 标准类在作用域退出时将变量设置为值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在成员函数的作用域内,我想临时将成员变量设置为某个值.

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 规范关于析构函数的默认异常规范一致.请参阅 cppreferenceSO Q&AGotW#47HIC++
  • 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆