将unique_ptr传递给什么都不做的自定义删除工具最简洁的方法是什么?我需要一个JNI函数我正在编写,其中C ++方需要unique_ptr,但是,我不希望在退出JNI函数时删除unique_ptr所持有的对象 - 我稍后会处理删除。所以我想做点什么:
std::unique_ptr<MyClass, noop_delete> ptr;
在一行中 - 没有单独的函数定义: - )
答案 0 :(得分:10)
正如@ 101010所指出的那样,std::unique_ptr
有一个nop删除器是非常奇怪的,因为std::unique_ptr
唯一有价值的东西实际上是删除器。另外,你说&#34; C ++方面需要unique_ptr&#34;,但是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类型可以在任何地方用作无操作,而不是单参数仿函数。
答案 1 :(得分:0)
我在@lisyarus的评论中对@lisyarus的问题的回答促使我提出了一个比在那儿给出的解决方案更好的解决方案。这处理了@lisyarus已经说明的事实:无操作删除器unique_ptr
的类型与带有unique_ptr
删除器的delete
的类型不同。
我将其作为单独的答案发布,因为它可能与其他人相关(此外,这不能在单个评论中显示)。
上下文:对于单元测试,FakeIt模拟框架管理模拟对象的生命周期,因此,当需要模拟通过unique_ptr指向的对象时,我们需要一个带no-op删除器的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。当然,在某些情况下,您需要#ifdef /#else并使用稍有不同的代码进行单元测试构建(可能在指针初始化的位置,但是如果还在此处创建了模拟,则需要仍要这样做)。但是,由于unique_ptr的界面不变,因此其余代码保持不变。