2016-04-03 17 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()関数を使用できるようにするには、たとえば次のようにします。あなたは、この動作が必要な場合は(あなたがstd::unique_ptrを使用する場合があります通常のコンテナは、その要素が指すオブジェクトを削除しないでください。

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 

このようなものを使用代わりに)。

+1

私はコンテナの要素がその時点のMOSTを指し示すオブジェクトを削除すべきでないことに同意します。この場合、パフォーマンスとコードの再利用性のためにこのクラスでこれを実装する方が有益です。私は、このクラスの関数を必要としないこの問題に対する2つの他の解決策を持っていますが、コード再利用性とパフォーマンス上の理由からそれらを使用したくありません。私はテンプレート関数の特殊化を試み、is_pointerでstatic_assertを追加して、この関数が非ポインタ型から呼び出されたかどうかを調べます。これまでのところ最高の答え、良い仕事。 –

+0

@DavidJones:どういうわけか、最初に非ポインタ型のクラスを使いたくないことを見落としました。残念です。 – MikeMB

+0

これはありがとうございます!私はデバッグしてチェックしていませんが、このシナリオではテンプレートクラスの関数テンプレートを使用してコンパイルします –

関連する問題