std::unique_ptr,自定义删除器和类型更改
std::unique_ptr, custom deleter and type change
我想在我的删除器中使用 unique_ptr。
我希望带有删除器的 unique_ptr 与带有默认删除器的 unique_ptr 完全兼容。
我这样做了:
template <typename T>
struct QObjectDeleteLaterDeletor :
public std::default_delete<T>
{
void operator()(T *p)
{
p->deleteLater();
}
};
template <typename T, class... Args>
std::unique_ptr<T> qtMakeUniqueSpecial(Args&&... args)
{
return std::unique_ptr<T>(
new T(std::forward<Args>(args)...),
QObjectDeleteLaterDeletor<T>());
}
这可以编译,但不起作用。我的自定义删除器被忽略并使用默认删除器,就好像我根本没有指定它一样。
我需要所有这些才能做这样的事情:
auto ptr1 = qtMakeUniqueSpecial<MyObject>();
std::unique_ptr<MyObject> ptr2;
ptr2 = std::move(ptr1);
请注意,现在即使 ptr1.reset() 也会导致调用标准删除器,而不是我的。
有可能吗?
您需要指定QObjectDeleteLaterDeletor
作为模板参数;否则,std::default_delete
将用作删除器,它是从 QObjectDeleteLaterDeletor
.
切片复制而来的
template <typename T, class... Args>
std::unique_ptr<T, QObjectDeleteLaterDeletor<T>> qtMakeUniqueSpecial(Args&&... args)
{
return std::unique_ptr<T, QObjectDeleteLaterDeletor<T>> (
new T(std::forward<Args>(args)...),
QObjectDeleteLaterDeletor<T>());
}
注意你把ptr2
声明为std::unique_ptr<MyObject>
,那么ptr2
会被std::default_delete
销毁指针。如果你声明它的类型符合 ptr1
就像 auto ptr2 = std::move(ptr1);
那么它会没事的。
您正在尝试使用
namespace std {
template<typename T, typename Deleter = default_delete<T> >
class unique_ptr;
}
它有第二个模板参数 Deleter
。如果没有指定,它默认为 std::default_delete<T>
。你的代码
std::unique_ptr<T>(new T(std::forward<Args>(args)...),
QObjectDeleteLaterDeletor<T>());
将 const std::default_delete<T>&
传递给 constructor of std::unique_ptr<T>
,因为这是构造函数所期望的。一旦销毁(或调用成员reset()
),这将被调用。
请注意 std::shared_ptr
的行为不同:删除器没有第二个模板参数,尽管在构造时可能会提供自定义删除器(这需要通过类型擦除来存储,这是避免使用 std::unique_ptr
).
我想在我的删除器中使用 unique_ptr。 我希望带有删除器的 unique_ptr 与带有默认删除器的 unique_ptr 完全兼容。
我这样做了:
template <typename T>
struct QObjectDeleteLaterDeletor :
public std::default_delete<T>
{
void operator()(T *p)
{
p->deleteLater();
}
};
template <typename T, class... Args>
std::unique_ptr<T> qtMakeUniqueSpecial(Args&&... args)
{
return std::unique_ptr<T>(
new T(std::forward<Args>(args)...),
QObjectDeleteLaterDeletor<T>());
}
这可以编译,但不起作用。我的自定义删除器被忽略并使用默认删除器,就好像我根本没有指定它一样。
我需要所有这些才能做这样的事情:
auto ptr1 = qtMakeUniqueSpecial<MyObject>();
std::unique_ptr<MyObject> ptr2;
ptr2 = std::move(ptr1);
请注意,现在即使 ptr1.reset() 也会导致调用标准删除器,而不是我的。
有可能吗?
您需要指定QObjectDeleteLaterDeletor
作为模板参数;否则,std::default_delete
将用作删除器,它是从 QObjectDeleteLaterDeletor
.
template <typename T, class... Args>
std::unique_ptr<T, QObjectDeleteLaterDeletor<T>> qtMakeUniqueSpecial(Args&&... args)
{
return std::unique_ptr<T, QObjectDeleteLaterDeletor<T>> (
new T(std::forward<Args>(args)...),
QObjectDeleteLaterDeletor<T>());
}
注意你把ptr2
声明为std::unique_ptr<MyObject>
,那么ptr2
会被std::default_delete
销毁指针。如果你声明它的类型符合 ptr1
就像 auto ptr2 = std::move(ptr1);
那么它会没事的。
您正在尝试使用
namespace std {
template<typename T, typename Deleter = default_delete<T> >
class unique_ptr;
}
它有第二个模板参数 Deleter
。如果没有指定,它默认为 std::default_delete<T>
。你的代码
std::unique_ptr<T>(new T(std::forward<Args>(args)...),
QObjectDeleteLaterDeletor<T>());
将 const std::default_delete<T>&
传递给 constructor of std::unique_ptr<T>
,因为这是构造函数所期望的。一旦销毁(或调用成员reset()
),这将被调用。
请注意 std::shared_ptr
的行为不同:删除器没有第二个模板参数,尽管在构造时可能会提供自定义删除器(这需要通过类型擦除来存储,这是避免使用 std::unique_ptr
).