unique_ptr 没有操作删除

No op delete for unique_ptr

传递 unique_ptr 不执行任何操作的自定义删除器的最简洁方法是什么?我需要一个正在编写的 JNI 函数,其中 C++ 端需要一个 unique_ptr,但是,我不希望 unique_ptr 持有的对象在退出 JNI 函数时被删除 - 我稍后注意删除。所以我想做类似的事情:

std::unique_ptr<MyClass, noop_delete> ptr;

在一行中 - 没有单独的函数定义:-)

正如@101010 所指出的,std::unique_ptr 带有 nop 删除器是非常奇怪的,因为 std::unique_ptr 唯一有价值的东西实际上是删除器。此外,您说 "C++ side expects a unique_ptr",但是具有不同删除器的 std::unique_ptr 将是 不同类型 ,这可能不起作用。

不过,方法如下:

struct nop
{
    template <typename T>
    void operator() (T const &) const noexcept { }
};

template <typename T>
using nop_unique_ptr = std::unique_ptr<T, nop>;

请注意,此 nop 类型可以在任何地方用作空操作来代替单参数仿函数。

我在对@lisyarus 的回答的评论中对他的问题的回答促使我想出了一个比我在那里给出的解决方案更好的解决方案。这涉及@lisyarus 已经陈述的事实:无操作删除器 unique_ptr 与带有 delete 删除器的 unique_ptr 属于不同类型。

我将此作为单独的答案发布,因为它可能与其他人相关(此外,这不适合单独发表评论)。

Context:对于单元测试,FakeIt 模拟框架管理模拟对象的生命周期,因此当需要模拟通过 unique_ptr 指向的对象时,我们需要一个带有空操作删除器的 unique_ptr。

// As in @lisyarus's answer...
struct nop
{
    template <typename T>
    void operator() (T const &) const noexcept { }
};

// NOTE: We have no use for a pointer that doesn't delete unless we're mocking, so 
// the types below are named to indicate that.

#ifndef WE_ARE_BUILDING_UNIT_TESTS
// Production build - we want a unique_ptr that deletes.
template <typename T>
using mockable_unique_ptr = std::unique_ptr<T>;
#else
// Unit test build - we want unique_ptr that doesn't delete.
template <typename T>
using mockable_unique_ptr = std::unique_ptr<T, nop>;
#endif

现在,mockable_unique_ptr 将根据构建类型自动切换类型,这意味着您不必在代码中到处添加#ifdef。当无论如何都要这样做)。不过,其余代码保持不变,因为 unique_ptr 的界面没有改变。

std::unique_ptr::release怎么样?如

void JNIfunc (T*) {};
std::make_unique( new T) t;
JNIfunc( t.release);