向unique_ptr传递一个什么都不做的自定义deleter最简洁的方法是什么?我需要一个我正在编写的JNI函数,其中C++端需要一个unique_ptr,但是,我不希望在退出JNI函数时删除unique_ptr-我稍后会处理删除。所以我想做一些类似的事情:
std::unique_ptr<MyClass, noop_delete> ptr;
在一行中-没有单独的函数定义:-)
正如@101010所指出的,有一个带有nop deleter的std::unique_ptr
是非常奇怪的,因为std::unique_ptr
唯一有价值的东西实际上是deleter。此外,您说过"C++端需要一个unique_ptr",但具有不同deleter的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类型可以在任何位置用作no操作,以代替单参数函子。
我在对@lisyarus的回答的评论中对他的问题的回答促使我想出了一个比我在那里给出的更好的解决方案。这处理了@lisyarus已经陈述的事实:无操作删除器unique_ptr
与具有delete
删除器的unique_ptr
的类型不同。
我将此作为单独的答案发布,因为它可能与其他人有关(此外,这不适合在一条评论中)。
Context:对于单元测试,FakeIt mocking框架管理mock对象的生存期,因此当需要对通过unique_ptr指向的对象进行mock时,我们需要一个不带操作删除器的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将根据构建类型自动切换类型,这意味着您不必在代码中到处添加#ifdefs。当然,在某些位置,您需要#ifdef/#else,并为单元测试构建使用稍微不同的代码(可能在指针初始化的位置,但如果您的mock也在那里创建,您无论如何都需要这样做)。不过,由于unique_ptr的接口没有更改,其余代码将保持不变。
std::unique_ptr::release
怎么样?如
void JNIfunc (T*) {};
std::make_unique( new T) t;
JNIfunc( t.release);