0

在阅读了关于在 C++ 中实现 Go 的延迟的问题后:

C ++中的golang风格的“延迟”

我对其中一个答案中给出的 go-defer like guard 子句的性能有疑问。它使用了一个 shared_ptr 删除器,它忽略了传递的对象地址。

如果删除器忽略了使用未命名参数的地址,它是否仍会在堆栈上传递。

以下任何一种实现延迟的方式会有什么不同吗?

#include <memory>
#include <iostream>
#include <functional>

using namespace std;
using defer = shared_ptr<void>;

int main() {
    defer defer0 (nullptr, [](...) { cout << "defer0\n"; }); // this is the version i've seen

    // but will the performance be any different using any of these?
    shared_ptr<int> defer1(nullptr, [](int* dummy) { cout << "defer1\n"; });
    shared_ptr<int> defer2(nullptr, [](int*) { cout << "defer2\n"; });
    shared_ptr<void> defer3(nullptr, [](void*) { cout << "defer3\n"; });

    unique_ptr<int,void(*)(int*)> defer4(nullptr, [](int*) { cout << "defer4\n"; });

    cout << "Hello\n";
}
4

1 回答 1

1

您可以在此处查看为每个实现构建的内容:godbolt

简而言之,版本 0-3 之间没有区别,指针在每种情况下都以相同的方式传递给删除器函数。

但是,如果您正在寻找性能,std::shared_ptr则为此目的使用 a 不是一个好主意。共享指针需要为资源计数分配内存,这对于终结器来说是完全没有必要的。

这种std::unique_ptr情况(使用虚拟变量,因此实际上调用了删除器)将以最少的开销工作。但是,更专注的课程会更明智。

于 2020-01-01T14:36:47.413 回答