2016-04-03 11 views
0

Sadece şablon tipi bir işaretçi olduğunda aşağıdaki işlevin çağrılmasını istiyorum. Aşağıdaki kod, t türünde bir şablon olan bağlantılı bir listenin (standart olmayan bir şey değil) bir fonksiyonudur. İşlev hiç çağrılmadığında bile şablon tipi bir işaretçi olmadığında bir derleme hatası atılıyor. Bir işlev, yalnızca işaretçi olmayan şablon türünden çağrılırsa ve bir işaretçi olan bir şablon türünden çağrıldığında oluşmaması durumunda bir hata atmak için bir yönteme ihtiyacım var. bir gösterici değildir silemezsiniz nesneler:Tip bir işaretçi değilse, şablon işlevinin çağrılması nasıl engellenir?

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 belirli hata kodu Hata C2541 'delete' dir. Bu, bu şablon türü için kodumun hiçbiri bu işlevi çağırmasa bile, 'imzasız kısa' olan bir şablon türünde gerçekleşiyor. Öneriler takdir edilecektir.

olarak, sadece öğrenmek istiyorsanız bu 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

ListeNode – MikeMB

+0

@MikeMB tanımının tanımlamasını gösterebilirsiniz Orijinali düzenlemek için orijinal gönderiyi düzenledim –

+0

Bunu yapmak zorunda kalıyorsanız, sınıfınız çok fazla şey yapıyor gibi geliyor. "Endişelerin ayrılması" konusuna bakın. – juanchopanza

cevap

1

tanımıdır talep sınıf yanlışlıkla karışmış işaretçi şablon parametresi türü ile kullanıldığı durumlarda kullanabileceğiniz static_assert:

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

    //other stuff 
}; 

ClearAndDelete() işlevinin işaretçi ve işaretçi olmayan tiplerde kullanılabilmesini istiyorsanız, örneğin; Böyle bir şey kullanın:

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

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

kullanımı:

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

: Bu davranış gerekiyorsa Genellikle kaplar onların elemanları işaret nesneleri silmemelisiniz (sen std::unique_ptr kullanmak isteyebilirsiniz yerine).

+1

Kapsayıcılara katılıyorum; öğelerinin, öğelerin MOST değerini işaret ettiği nesneleri silmemelidir. Bu durumda, performans ve kod yeniden kullanılabilirliği için bu sınıfta bunu uygulamak daha yararlıdır, neden isteyip istemediğinizi açıklayabilirim. Bu soruna, bu sınıfta bir işlev gerektirmeyen iki başka çözümüm var ama bunları yeniden kullanılabilirlik ve performans nedenleriyle kullanmamayı tercih ediyorum. Bir yan not üzerinde, bu işlevin işaretçi olmayan bir türden çağrılıp çağrılmadığını yakalamak için şablon işlev uzmanlığını deneyeceğim ve is_pointer ile static_assert ekleyeceğim. Şimdiye kadarki en iyi cevap, iyi iş. –

+0

@DavidJones: Her nasılsa, ilk önce bir işaretçi türü olmayan sınıfı kullanmak istemediğinizi unutmuştum - bunun için üzgünüm. – MikeMB

+0

Bu çalışır teşekkür ederim! Hata ayıklamamış ve kontrol etmemiştir ancak bu senaryo için bir şablon sınıfında bir işlev şablonu kullanmaktadır, –

İlgili konular