【发布时间】:2021-08-19 08:41:39
【问题描述】:
我想要一个成员函数 unique-ptr 和一个静态删除函数,该函数在编译时是已知的,并且在分配时不需要函数指针。我不知道这是否可能,但this test 让我感到困惑:
#include <memory>
#include <string>
#include <iostream>
struct Apa {
std::string name;
~Apa() {
std::cout << name << " deleted\n";
}
};
static void staticDeleter(Apa *a) {
std::cout << "static deleter\n";
delete a;
}
int main() {
auto deleter = [] (Apa *a) {
std::cout << "deleter\n";
delete a;
};
{
// This is what I want but as a member of a struct
auto ptr1 = std::unique_ptr<Apa, decltype(deleter)>{new Apa{"Apan"}}; // <----------------
std::cout << sizeof(ptr1) << " -> Apan\n";
}
{
auto ptr2 = std::unique_ptr<Apa, decltype(&staticDeleter)>(new Apa{"Beata"}, staticDeleter);
// When trying to omit this argument this line does not compile ------------^
std::cout << sizeof(ptr2) << " -> Beta\n";
}
}
这会导致输出
8 -> Apan
deleter
Apan deleted
16 -> Beta
static deleter
Beata deleted
因此,除非有一些未知的编译器魔法,否则指针的大小表明实际上可以使用静态删除函数创建唯一的 ptr。
当尝试在结构中做同样的事情时
#include <memory>
#include <iostream>
struct Apa{
};
struct Container {
using deleter = decltype((Apa*) {}); // Edit: This was a typo: se below
std::unique_ptr<Apa, deleter> ptr ;
};
int main() {
std::cout << sizeof(Container::ptr) << "\n";
}
输出 16 表明 unique_ptr 确实需要指向删除函数的指针。
有什么办法可以让我在静态定义而不是在运行时指定的类中定义一个带有自定义删除器函数的 unique_ptr?
编辑:
经过@eeerorika 的一些反馈后,我意识到如果 lambda 编写正确,代码实际上可以工作。 Working code:
#include <memory>
#include <iostream>
struct Apa{
~Apa() {
std::cout << "Apa deleted\n";
}
};
struct Container {
using deleter = decltype([](Apa* apa) {
std::cout << "deleter\n";
delete apa;
});
std::unique_ptr<Apa, deleter> ptr = std::unique_ptr<Apa, deleter>{new Apa} ;
};
int main() {
std::cout << sizeof(Container::ptr) << "\n";
Container container{};
}
产量输出:
8
deleter
Apa deleted
【问题讨论】:
-
这是用于 pimpl 模式(指向实现的指针),还是用于在销毁期间挂钩某些附加行为(例如,向侦听器发出销毁通知)、调试助手或其他东西还有吗?
-
它用于包装一个 c 库,而不必手动指定析构函数。
-
啊,太好了!很好地使用智能指针来管理外来对象的生命周期。
标签: c++ unique-ptr