如何使用静态删除器创建 unique_ptr

激光防护罩

我想要一个带有静态删除器函数的成员函数 unique-ptr,该函数在编译时已知,并且在分配时不需要函数指针。我不知道是否有可能,但这个测试让我感到困惑:

#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 吗?

编辑:

在@eerorika 提供一些反馈后,我意识到如果 lambda 编写正确,代码实际上可以工作。工作代码

#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
埃罗里卡
using deleter = decltype((Apa*) {});

这是一种不必要的复杂的写作方式:

using deleter = Apa*;

该类型Apa*不满足std::unique_ptr强加于其删除器的要求,因为Apa*它不是 FunctionObject。示例程序格式错误(至少如果您尝试创建它的实例)。因此,对象的大小无关紧要。

有什么方法可以使这项工作起作用,以便我在静态定义而不是在运行时指定的类中定义带有自定义删除器函数的 unique_ptr 吗?

你的 lambda 示例从 C++20 开始工作。您可以将类似的删除器定义为一个类,它也适用于早期版本。例如:

struct deleter {
    void operator()(Apa* ptr) {
        std::cout << "custom deleter\n";
        delete ptr;
    }
};

struct Container {
    std::unique_ptr<Apa, deleter> ptr  ;
};

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章