用Std::bind初始化Std::shared_ptr的Std::get_deleter
std::get_deleter on std::shared_ptr initialized with std::bind
假设我有这样的代码:
class BaseObject
{
public:
virtual void OnDestroy() {}
};
template <typename T>
struct myArrayDeleter
{
void operator()(T *p, std::size_t count)
{
for(std::size_t i = 0; i < count; i++)
{
static_cast<BaseObject*>((void*)(int(p) + sizeof(T) * i))->OnDestroy();
}
delete [] p;
}
};
让我们假设它按预期工作(这是一个简化版本,现在没有检查,但基本上你知道这段代码应该做什么)。
这部分我没有问题。但是,看看这个:
class AActor
: public BaseObject
{
public:
virtual void OnDestroy() override
{
// some code here
}
};
template <typename T>
class SimplifiedHolder
{
protected:
std::shared_ptr<T> m_shared;
std::size_t m_size;
public:
// Some not important code here
// WE ASSUME HERE THAT IT ALWAYS HOLDS ARRAY
// sizeOfArray always > 1
template <typename U>
SimplifiedHolder(U *ptr, std::size_t sizeOfArray)
: m_size(sizeOfArray)
{
m_shared = std::shared_ptr<T>(ptr,
std::bind(&myArrayDeleter<U>(), std::placeholders::_1, m_size));
}
// And now as we initialize our shared_ptr with template
// we can check if it is exactly of type "U"
template <typename U>
bool IsExactlyOfType()
{
if(!m_shared)
return false;
return ((void*)std::get_deleter<myArrayDeleter<U>>(m_shared)) != nullptr;
}
};
然而,方法IsExactlyOfType
不起作用。这是因为我用std::bind
初始化了shared_ptr
。std::get_deleter
总是返回nullptr
,因为模板中指定了错误的类型。我不知道该传递哪种类型。我还尝试了非数组代码,其中myDeleter
是一个只有一个参数的函子,它与这样的代码完美地工作:
template <typename U>
bool IsExactlyOfType()
{
if(!m_shared)
return false;
return ((void*)std::get_deleter<myDeleter<U>>(m_shared) != nullptr;
}
我知道我可以用typeid(U) == typeid(*m_shared.get())
,但这不是我想要的。我有更复杂的代码,在这种情况下,只有这个方法是好的。
有经验的程序员能告诉我该给std::get_deleter
指定什么类型吗
原来编译器没有正确翻译decltype。我试图在初始化shared_ptr后立即删除它,它工作了。然而,同样的decltype在函数中生成了稍微不同的类型。我在调试器中检查了它,它生成了以下结果:
在构造函数:std::_Binder<std::_Unforced,grim::impl::TObjectArrayDeleter<APlayer>,std::_Ph<1> const &,unsigned int &> &
在功能:std::_Binder<std::_Unforced,grim::impl::TObjectArrayDeleter<APlayer>,std::_Ph<1> const &,unsigned int const &> *
看一下结尾处——它附加了额外的const。我需要手动更改它,所以现在我的代码看起来像这样:
using D = std::_Binder<std::_Unforced,grim::impl::TObjectArrayDeleter<U>,
std::_Ph<1> const &,unsigned int &>;
return ((void*)std::get_deleter<D>(m_shared)) != nullptr;
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 带有自定义deleter的std::unique_ptr对象的大小(一个由ref捕获的lambda)
- 使用自定义deleter类型定义std::shared_ptr的别名
- C++11 std::unique_ptr deleter
- std::unique_ptr的自定义deleter是手动调用析构函数的有效位置吗
- 使用std::shared_ptr将成员函数用作自定义deleter时出现问题
- 将std::unique_ptr与lambda交换为deleter--GCC
- 使用std::unique_ptr的静态函数deleter时出错
- 自定义deleter以通过std::unique_ptr解除分配2D阵列
- std::unique_ptr将deleter作为类型的一部分有什么好处