我有一个带模板的通用列表
template<class t>
class GenericList {
//the data is storeed in a chained list, this is not really important.
struct c_list { t data; c_list* next; ...constructor... };
public:
bool isDelete;
GenericList() : isDelete(false) {...}
void add(t d) {
c_list* tmp = new c_list(d, first->next);
//this is not really important again...
}
~GenericList() {
c_list* tmp = first;
c_list* tmp2;
while(tmp->next!=NULL) {
if (isDelete) { delete tmp->data; } //important part
tmp2=tmp->next;
delete tmp;
tmp=tmp2;
}
}
};
重要的部分是isDelete
这只是示例代码
我需要这个,因为我想存储这样的数据:
GenericList<int> list;
list.add(22);list.add(33);
以及
GenericList<string*> list;
list.add(new string("asd")); list.add(new string("watta"));
问题如果我只存储<int>
编译器说我不能删除非指针变量,但我不想在这种情况下。我怎么解决这个问题呢?
当我存储<int*>
时,没有编译器错误......
答案 0 :(得分:3)
在不改变代码的情况下,我会将您的问题解决为
template<class t>
class GenericList
{
//same as before
//add this function template
template<typename T>
void delete_if_pointer(T & item) {} //do nothing: item is not pointer
template<typename T>
void delete_if_pointer(T* item) { delete item; } //delete: item is pointer
~GenericList() {
c_list* tmp = first;
c_list* tmp2;
while(tmp->next!=NULL) {
delete_if_pointer(tmp->data); // call the function template
tmp2=tmp->next;
delete tmp;
tmp=tmp2;
}
}
};
data
的类型;编译器自动推导出它。但是,@ ildjarn的解决方案要求您明确提及类型;编译器无法推断出他的解决方案中的类型。
答案 1 :(得分:1)
我会在你的类中创建一个嵌套的struct模板来帮助:
template<typename U>
struct deleter
{
static void invoke(U const&) { }
};
template<typename U>
struct deleter<U*>
{
static void invoke(U* const ptr) { delete ptr; }
};
然后从
更改使用isDelete
的行
if (isDelete) { delete tmp->data; }
到
if (isDelete) { deleter<t>::invoke(tmp->data); }
答案 2 :(得分:0)
delete
上的{p> int
会导致程序格式错误,因此编译器会拒绝它,即使永远不会达到delete
。
只有从“裸”指针切换到智能指针(例如unique_ptr
或shared_ptr
),才能实现所需;那些没有明确delete
的处理内存管理。