为了账号安全,请及时绑定邮箱和手机立即绑定

C ++中的golang样式“延迟”

C ++中的golang样式“延迟”

Go
烙印99 2021-11-15 15:50:04
我正在阅读 go 语言的defer语句。它允许您指定在函数结束时要采取的操作。例如,如果您有一个文件指针或资源,则无需使用每个可能的返回路径编写 free/delete,您只需指定一次 defer 函数。看起来类似的东西最终可能会出现在 C++ 中(C++中的标准延迟/终结器实现是什么?,是否会有范围保护/范围退出习惯用法的标准化?)在此之前,使用具有析构函数进行回调?看起来局部变量的析构函数顺序是合理的,它也能很好地处理异常,尽管可能不会在信号上退出。这是一个示例实现......有什么问题吗?#include <iostream>#include <functional>using namespace std;class FrameExitTask {    std::function<void()> func_;public:    FrameExitTask(std::function<void()> func) :    func_(func) {    }    ~FrameExitTask() {        func_();    }    FrameExitTask& operator=(const FrameExitTask&) = delete;    FrameExitTask(const FrameExitTask&) = delete;};int main() {    FrameExitTask outer_task([](){cout << "world!";});    FrameExitTask inner_task([](){cout << "Hello, ";});    if (1+1 == 2)        return -1;    FrameExitTask skipped_task([](){cout << "Blam";});}输出: Hello, world!
查看完整描述

3 回答

?
呼唤远方

TA贡献1856条经验 获得超11个赞

Boost 在 Smart Pointer Programming Techniques 中对此进行了讨论:


http://www.boost.org/doc/libs/1_59_0/libs/smart_ptr/sp_techniques.html#handle

你可以这样做,例如:


#include <memory>

#include <iostream>

#include <functional>


using namespace std;

using defer = shared_ptr<void>;    


int main() {

    defer _(nullptr, bind([]{ cout << ", World!"; }));

    cout << "Hello";

}

或者,没有bind:


#include <memory>

#include <iostream>


using namespace std;

using defer = shared_ptr<void>;    


int main() {

    defer _(nullptr, [](...){ cout << ", World!"; });

    cout << "Hello";

}


查看完整回答
反对 回复 2021-11-15
?
暮色呼如

TA贡献1853条经验 获得超9个赞

这已经存在,它被称为范围保护。看到这个精彩的演讲:https : //channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C。这使您可以轻松创建要在退出时调用的任意可调用对象。这是较新的版本;它最初是在 go 出现之前很久就被开发出来的。

它在一般情况下完美运行,但我不确定你所说的处理异常是什么意思。从必须在作用域退出时调用的函数抛出异常是一团糟。原因:当抛出异常(而不是立即捕获)时,当前作用域退出。所有析构函数都会运行,异常将继续传播。如果其中一个析构函数抛出异常,你会怎么做?您现在有两个实时异常。

我想有一种语言可以尝试处理这个问题,但它非常复杂。在 C++ 中,抛出析构函数被认为是一个好主意是非常罕见的。


查看完整回答
反对 回复 2021-11-15
?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

这在 C++ 中已经存在,这是一个非常糟糕的主意,你给出的例子说明了为什么这是一件毫无意义的事情,我希望委员会永远不会引入它。

例如,如果您有一个文件句柄,然后编写一个类来为您完成它,然后您就不必为每个用例编写 defer 语句,而您很容易忘记这样做。或者只是简单地弄错了。你写一个析构函数,一次。就是这样。然后,您可以保证该类的所有用途都是安全的。它更安全,更容易。


查看完整回答
反对 回复 2021-11-15
  • 3 回答
  • 0 关注
  • 220 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信