2016-04-03 46 views
0

我只希望在模板類型是指針時調用下面的函數。下面的代碼是一個鏈接列表(自定義類,不是任何標準)的函數,它是類型爲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; 
     } 
    }; 
+0

你可以顯示的是ListNode的定義 – MikeMB

+0

@MikeMB我編輯原始文章包括它 –

+0

如果你發現自己不得不這樣做,這聽起來像你的班級做得太多了。查找「關注點分離」。 – juanchopanza

回答

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代替)。

+1

我同意容器不應該刪除它們的元素指向大部分時間的對象。在這種情況下,爲了提高性能和代碼的可用性,在這個類中實現這個更有用,我可以解釋爲什麼如果你願意的話。我對這個問題有另外兩個解決方案,它們不需要這個類中的函數,但我寧願不將它們用於代碼重用性和性能方面的原因。在一個側面說明我會嘗試模板函數專門化,並添加static_assert與is_pointer來捕獲,如果這個函數曾經從非指針類型調用。迄今爲止的最佳答案,很好。 –

+0

@DavidJones:不知何故,我忽略了你不想首先使用非指針類型的類 - 對不起。 – MikeMB

+0

這個作品謝謝你!我沒有調試和檢查它,但使用模板類中的函數模板編譯這個場景, –

相關問題