如果类型不是指针,如何限制模板函数被调用?

时间:2016-04-03 17:16:21

标签: c++ templates pointers

我只希望在模板类型是指针时调用以下函数。下面的代码是一个链接列表(自定义类,而不是任何标准)的函数,它是类型为t的模板。当模板类型不是指针时,即使根本没有调用该函数,也会抛出编译错误。我需要一种方法只有在从非指针模板类型调用函数时抛出错误,如果从作为指针的模板类型调用它,则不会发生错误。

virtual void ClearAndDelete()
    {
        ListNode<t> * ptr = this->FirstNode;
        for (; ptr != nullptr; )
        {
            ListNode<t> * nextptr = ptr->Next;
            delete ptr->Item;//ERROR C2541
            delete ptr;
            ptr = nextptr;
        }

        this->TotalNodes = 0;
        this->FirstNode = nullptr;
        this->LastNode = nullptr;
    }

Visual Studio 2015的特定错误代码是 错误C2541'删除':无法删除不是指针的对象。这发生在'unsigned short'的模板类型上,即使我的该模板类型的代码都没有调用此函数。建议将不胜感激。

根据要求,这是ListNode的定义

template<typename t> struct ListNode
    {
    public:
        t Item;
        ListNode<t> * Next;
        ListNode(t what) : Item(what)
        {
            this->Next = nullptr;
        }
        ListNode(t what, ListNode<t> * nextnode) : Item(what)
        {
            this->Next = nextnode;
        }
    };

1 个答案:

答案 0 :(得分:1)

如果您只是想知道,您的类被错误地用于非指针模板参数类型,您可以使用static_assert

template<class t>
class List {
    static_assert(!std::is_pointer<t>::value, "Template parameter must be of pointer type");

    //other stuff
};

如果希望ClearAndDelete()函数可用于指针和非指针类型,则可以使用使用这样的东西:

template<class T>
void deleteIfPointer(const T& element) {}

template<class T>
void deleteIfPointer(T* ptr) {  
    delete ptr; 
}

用法:

deleteIfPointer(ptr->Item); //instead of delete ptr->Item

旁注:通常容器不应删除其元素指向的对象(如果需要此行为,则可能需要使用std::unique_ptr)。