我试图将VkInstance(不透明指针) Package 到unique_ptr
中,但似乎无法实现。
...
VkInstance instance;
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS) {
throw std::runtime_error("failed to create vulkan instance");
}
auto del = [](VkInstance* p) {
DBG("release vk instance");
vkDestroyInstance(*p, nullptr);
};
auto ptr = std::unique_ptr<VkInstance, decltype(del)>(instance, del);
...
错误:
no instance of constructor "std::unique_ptr<_Tp, _Dp>::unique_ptr [with _Tp=VkInstance, _Dp=lambda [](VkInstance *p)->void]" matches the argument list
我不知道为什么,VkInstance是一个指针,所以我传递它,deleter必须接受指向内存地址的指针,所以它仍然接收它,但是类型仍然不匹配。
用&
去引用它并将其传递给make_unique会导致segfault。
唯一的方法,我设法使它的工作只与额外的新调用,像这样:
...
VkInstance* instance = new VkInstance;
if (vkCreateInstance(&createInfo, nullptr, instance) != VK_SUCCESS) {
throw std::runtime_error("failed to create vulkan instance");
}
auto del = [](VkInstance* p) {
DBG("release vk instance");
vkDestroyInstance(*p, nullptr);
};
auto ptr = std::unique_ptr<VkInstance, decltype(del)>(instance, del);
...
但这是一个有点荒谬的解决方案,因为我是动态分配的东西,应该放在一个CPU寄存器,并几乎立即转移到unique_ptr
控制区。
那么,我能以某种方式实现我试图做的事情,而不需要进一步的过度设计吗?
4条答案
按热度按时间3duebb1j1#
std::unique_ptr
可以处理甚至不是指针的类型;它当然可以与VkInstance
这样的不透明指针类型一起工作。但是,您必须知道如何按照std::unique_ptr
预期的方式做事。关键在于:
unique_ptr
的deleter类型有很多有用的功能,如果你使用lambda类型,这些功能都不能用。另外,如果你想使用一个函子的类型名,必须做decltype
体操,而不是仅仅给它一个名字,这有点俗气。因此,做一个适当的删除器:
InstPtr
现在可以用来管理VkInstance
对象,唯一的问题是你不能在上面使用->
,但这在Vulkan中没有任何意义。cbjzeqam2#
我想您在将“instance”对象传递给std::unique_ptr构造函数时忘记了该对象上的&:
您可以在这里尝试:https://tio.run/##RY1BDoIwFETX/FN8MTGtwQvQytJLqDGkFNIE2gq/C0I4e61E4vbNzBvl/aVTKsajsaoPjUZp3ESjrocK/mzQgxvnCiBFQRHenIMFVgFgLOFQG8t4Alni2ArI6kAOG91r0iNe8f5kKTljy5eJmrJULhBKiflWMbZDQ4eHzcW6bz19d1s5WPMO@pWITJIiaVVPs9fs5@cVO7XF/sYFrDF@AA
lhcgjxsq3#
问题是
VkInstance
是一个指针,而不是“指向类型”,所以基本上你应该有类似std::unique_ptr<VkInstancePointee>
的东西。但是因为我们没有这种类型,这基本上是Vulkan的实现细节,可以在不通知的情况下更改,所以最好不要使用它。所以如果你想要RAII行为,你只需要创建 Package 器。类似这样:wgx48brx4#
所以,经过更多的研究,我想我需要这样的东西:
从这里找到了这些:非指针上RAII的一行程序?
这些都没有实现,但是符合一般的RAII概念,所以,看起来唯一指针只用于指针分配的资源,而不是值资源,在我的例子中是不透明句柄。