对这个标题感到抱歉,我无法提供更好的标题。
假设我有一个具有特殊删除语义的类,它需要调用函数而不是被delete
删除,我们称之为releaseable_object
:
struct releaseable_object
{
releaseable_object() : dummy_ptr(new int) {}
void Release()
{
std::cout << "Releasing releaseable object\n";
delete dummy_ptr;
}
int *const dummy_ptr;
};
这个releaseable_object
是一堆其他对象的基类,每个对象都是由一个仅返回指针的工厂构造的。
我试图使用自定义删除器将每个类包装到 std::unique_ptr
中,该删除器调用 releaseable_object::Release()
函数,所以我创建了一个辅助结构来处理一些通用的东西:
// std::is_base_of<releaseable_object, T>::value must be true
template <typename T> struct Managed
{
using type = T;
static void deleter(type *object)
{
std::cout << "Release!\n";
object->Release();
};
using pointer = std::unique_ptr<T, decltype(deleter)>;
};
然后,一堆派生类完成所有特定的初始化并调用工厂:
struct ManagedA : Managed<A>
{
using base = Managed<A>;
using base::pointer;
using base::deleter;
ManagedA(/* lots of parameters */) :
m_pointer(nullptr, deleter)
{
// do A specific stuff...
A *a = factory::CreateA(/* lots of parameters */);
// more A specific stuff...
// wrap the pointer:
m_pointer.reset(a);
}
pointer m_pointer;
};
如果我尝试编译上面的代码,它会提示 unique_ptr
( demo here ),我不知道我在那里做错了什么,错误与实例化有关一个元组(完整的错误日志在 ideone demo 中):
tuple: In instantiation of ‘struct std::_Head_base<1u, void(A*), false>’:
tuple:229:12: recursively required from ‘struct std::_Tuple_impl<1u, void(A*)>’
tuple:229:12: required from ‘struct std::_Tuple_impl<0u, A*, void(A*)>’
tuple:521:11: required from ‘class std::tuple<A*, void(A*)>’
bits/unique_ptr.h:127:57: required from ‘class std::unique_ptr<A, void(A*)>’
如果我去掉 m_pointer
成员,那么编译就会成功。我对此感到非常困惑,如果有任何有关如何修复编译错误的提示,我将不胜感激。
感谢您的关注。
最佳答案
问题是 decltype(deleter)
是函数类型而不是函数指针类型。将指针
声明更改为
using pointer = std::unique_ptr<T, decltype(deleter)*>; // or spell out void(*)(T*)
会修复它。
请注意,对于唯一指针删除器,函数对象类型通常优于函数指针类型,因为函数指针必须存储在对象本身中。即,
sizeof(std::unique_ptr<foo*,void(*)(foo*)>) == sizeof(foo*) + sizeof(void(*)(foo*))
但如果您使用空删除器类型,大多数实现都会利用空基础优化:
struct deleter_type {
void operator () (foo*) {
// ...
}
};
sizeof(std::unique_ptr<foo*,deleter_type>) == sizeof(foo*)
Here's how your sample code would be written using a deleter type. .
关于c++11 - 在基类上声明的 std::unique_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21707279/