C++ 通用列表删除非指针

C++ 通用列表删除非指针,c++,pointers,generic-list,delete-operator,C++,Pointers,Generic List,Delete Operator,我有一个带有模板的通用列表 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() : isDele

我有一个带有模板的通用列表

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;

        }
    }
};
模板
类泛型列表{
//数据存储在链表中,这并不重要。
结构c_列表{t数据;c_列表*下一步;…构造函数…};
公众:
布尔·伊斯德莱特;
GenericList():isDelete(false){…}
无效添加(t d){
c_列表*tmp=新的c_列表(d,第一个->下一个);
//这真的不再重要了。。。
}
~GenericList(){
c_列表*tmp=第一;
c_列表*tmp2;
while(tmp->next!=NULL){
if(isDelete){删除tmp->data;}//重要部分
tmp2=tmp->next;
删除tmp;
tmp=tmp2;
}
}
};
重要的部分是isDelete
这只是一个示例代码

我需要这个,因为我想像这样存储数据:

GenericList<int> list;
list.add(22);list.add(33);
通用列表;
增加(22);增加(33);
而且

GenericList<string*> list;
list.add(new string("asd")); list.add(new string("watta"));
通用列表;
添加(新字符串(“asd”);添加(新字符串(“watta”);

如果我只存储
的问题编译器说我不能删除非指针变量,但在这种情况下我不想删除。我如何解决这个问题?

当我存储
时,没有编译器错误…

int
上删除
会使程序格式错误,因此编译器将拒绝它,即使永远无法到达
删除


只有从“裸”指针切换到智能指针(如
unique_ptr
shared_ptr
)时,才能实现您想要的功能;它们为您处理内存管理,在
int
上没有显式的
delete

delete
会使程序格式错误,因此编译器将拒绝它,即使永远无法到达
delete


只有从“裸”指针切换到智能指针(如
unique_ptr
shared_ptr
)时,才能实现您想要的功能;这些为您处理内存管理,而无需显式地
delete

我将在类中创建嵌套结构模板以帮助:

template<typename U>
struct deleter
{
    static void invoke(U const&) { }
};

template<typename U>
struct deleter<U*>
{
    static void invoke(U* const ptr) { delete ptr; }
};

if(isDelete){deleter::invoke(tmp->data);}

我会在类中创建嵌套结构模板,以帮助:

template<typename U>
struct deleter
{
    static void invoke(U const&) { }
};

template<typename U>
struct deleter<U*>
{
    static void invoke(U* const ptr) { delete ptr; }
};

if(isDelete){deleter::invoke(tmp->data);}

在不改变您的代码的情况下,我会像您一样解决您的问题

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;
       }
   }
};
模板
类泛型列表
{
//和以前一样
//添加此函数模板
模板
void delete_如果_指针(T&item){}//什么也不做:item不是指针
模板
void delete_如果_指针(T*item){delete item;}//delete:item是指针
~GenericList(){
c_列表*tmp=第一;
c_列表*tmp2;
while(tmp->next!=NULL){
删除_if_指针(tmp->data);//调用函数模板
tmp2=tmp->next;
删除tmp;
tmp=tmp2;
}
}
};


编辑:我刚刚注意到@ildjarn提供了类似的解决方案。但是有一个有趣的区别:我的解决方案不要求您在调用函数模板时提及
数据的类型
;编译器会自动推断它@然而,ildjarn的解决方案要求您明确地提到类型;编译器无法在其解决方案中推断出类型。

如果不对您的代码进行太多更改,我将按如下方式解决您的问题

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;
       }
   }
};
模板
类泛型列表
{
//和以前一样
//添加此函数模板
模板
void delete_如果_指针(T&item){}//什么也不做:item不是指针
模板
void delete_如果_指针(T*item){delete item;}//delete:item是指针
~GenericList(){
c_列表*tmp=第一;
c_列表*tmp2;
while(tmp->next!=NULL){
删除_if_指针(tmp->data);//调用函数模板
tmp2=tmp->next;
删除tmp;
tmp=tmp2;
}
}
};


编辑:我刚刚注意到@ildjarn提供了类似的解决方案。但是有一个有趣的区别:我的解决方案不要求您在调用函数模板时提及
数据的类型
;编译器会自动推断它@然而,ildjarn的解决方案要求您明确地提到类型;编译器无法推断出其解决方案中的类型。

@ildjarn:我正在使用
&
。这足以避免复制@伊尔贾恩:反正我用的是
&
。这足以避免复制!