我正在编写一个清理实用程序,它将在元组中存储要清理的项目,如果出现错误,则会对元组中的每个项目执行适当的操作。元组中的一些典型项是指向堆上分配的对象的指针。当我的清理处理程序决定删除这些对象时,它必须知道它是否应该使用vanilla delete表达式或delete表达式的数组形式(delete [])。我如何确定元组中的项是指向单个对象的指针还是指向对象数组的指针。
这是sample implementation。以下是与此问题相关的部分:
template<unsigned index, typename... Types>
struct TupleItemDeleter
{
void operator() (std::tuple<Types...>& t)
{
std::cout << "Deleting item at index " << index << std::endl;
delete std::get<index>(t); //HOWTO: delete[] or delete?
TupleItemDeleter<index - 1, Types...>{}(t);
}
};
template<typename... Types>
struct TupleItemDeleter<0, Types...>
{
void operator() (std::tuple<Types...>& t)
{
std::cout << "Deleting item at index 0" << std::endl;
delete std::get<0>(t); //HOWTO: delete[] or delete?
}
};
template<typename... Types>
void deleter(std::tuple<Types...>& t)
{
constexpr auto tupleSize = std::tuple_size<std::tuple<Types...>>::value;
TupleItemDeleter<tupleSize - 1, Types...>{}(t);
}
PS:我试过std :: is_array,在我的情况下没用。
答案 0 :(得分:3)
你只能从指针告诉它是指向单个对象还是数组 - 这就是为什么有两种形式的delete
,因为编译器不能告诉你。您需要以其他方式跟踪信息。
由于您已经在使用元组,或许您可以在那里存储指示符。
答案 1 :(得分:1)
问自己的问题是代码当前如何知道指针指向数组,即它如何知道它可以安全地索引指针,还有多少?
如果有一些模型,即使它只是一个约定而且编码不好,那么你需要找到一些方法将该约定传递给你的元组。
一种方法是为那些需要删除数组的元素存储一对指针/成员,即使你不使用计数,或创建一个也包含计数的智能指针包装器,并开始使用他们在更多的代码中。
另一个想法是某些类可能总是分配数组而其他类永远不会。您可以自己编写一个特性,告诉您每个类的行为,或者您可以将destroy()添加到对每个类执行正确操作的类中。您也可以假设任何指向简单类型的指针都可能是数组分配的,例如字符指针可能是一个字符串。
如果您可以更积极地替换类的分配器,而不实际编辑遗留代码,则可以确定具有该问题的类的所有运算符new()实际上调用operator new并且计数为1;或者所有运算符new()都将地址记录到哈希表中。如果找到了地址,则需要使用operator delete。