繁体   English   中英

如何将没有自定义删除器的 unique_ptr 移动到另一个使用自定义删除器的 unique_ptr?

[英]How to move a unique_ptr without custom deleter to another unique_ptr with custom deleter?

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

struct TestStruct {
    int a = 100;
};

struct StructDeleter {
    void operator()(TestStruct *ptr) const {
        delete ptr;
    }
};

std::unique_ptr<TestStruct, StructDeleter> MakeNewStruct() {
    std::unique_ptr<TestStruct> st(new TestStruct());

    std::unique_ptr<TestStruct, StructDeleter> customDeleterSt(std::move(st));
    std::cout << customDeleterSt->a << std::endl;
    return customDeleterSt;
}

int main() {
    auto a = MakeNewStruct();
    std::cout << a->a << std::endl;
    return 0;
}

上面的代码无法编译,如何将st移动到customDeleterSt 我从st创建界面获得了一个st unique_ptr,并且我使用自定义删除器向我的用户隐藏了st的实现,那么如何将没有自定义删除器的 unique_ptr 移动到带有自定义删除器的 unique_tr 呢?

谢谢你的帮助!

如评论中所述,蛮力方法是将源.release()传递给目标的构造函数。 然而,有一个更优雅的解决方案(恕我直言):

添加从std::default_delete<TestStruct>StructDeleter的隐式转换:

struct StructDeleter {
    StructDeleter(std::default_delete<TestStruct>) {}  // Add this

    void operator()(TestStruct *ptr) const {
        delete ptr;
    }
};

现在代码可以使用现有的移动构造语法。

无论这是通过转换构造函数还是.release()来完成,如果StructDeleter不能(出于任何原因)正确删除std::default_delete处理的指针,这将导致未定义的行为。 只是因为StructDeleter调用了delete ptr ,这些技术中的任何一种都有效。

如所写, TestStructdelete点不需要是一个完整的类型。 但是,如果TestStruct获得一个重要的析构函数,您还需要确保对于任何调用StructDeleter::operator()(TestStruct*)的代码, TestStruct是一个完整的类型,否则您将再次回到 UB 领域。 这种保证是std::default_delete<TestStruct>为您做的事情之一,StructDeleter (如所写)没有。

如果打算保持~TestStruct()微不足道,最好添加:

static_assert(std::is_trivially_destructible<TestStruct>::value);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM