2012-03-12 13 views
3

基本操作をstd :: mapに追加するクラスを作っていますが、を呼び出すと、マップから項目を削除した後に自動的に呼び出されます。しかし、2番目の値(T2)がポインタでない場合、これは実行できません。確認する方法はありますか?値がポインタの場合にのみ呼び出す

template <class T,class T2> 
bool CExtendedMap<T,T2>::remove(T ID) 
{ 
    if(theMap.find(ID)!=theMap.end()) 
    { 
     T2 second = theMap.find(ID)->second; 
     theMap.erase(theMap.find(ID)); 
     //delete second; //Had to comment it out now. 
     return true; 
    } 
    return false; 
} 

答えて

5

私があなたの質問を正しく理解している場合、あなたのCExtendedMapに格納されているペアの値がポインタであるかどうかが異なる場合、異なる動作をしたいと思います。

問題を解決する簡単な方法の1つは、テンプレートオーバーロードを使用して目的の効果を得ることです。

パラメータがポインタの場合はdeleteを使用するラッパー関数を実装します。そうでない場合は何もしません。これははるかに簡単な解決方法です。

実装例を以下に示す:

template<class T> inline 
void delete_or_nop (T const&) {/* NOP */} 

template<class T> inline 
void delete_or_nop (T* const& p) {delete p;} 

int 
main (int argc, char *argv[]) 
{ 
    int * p = 0; 
    int n = 0; 

    delete_or_nop (p); 
    delete_or_nop (n); 
} 
+0

コピー品は高価になる可能性がありますので参考にしてください。 – Xeo

+0

@Xeo固定、編集後編集。 –

+0

私は自分自身を考えていないと信じられない..どのように愚か! – natli

8

代わりにスマートポインタを使用すると、何かを削除する心配がありません。メモリは、eraseの要素をマップから解放すると解放されます。

+3

ブーストをもう一度開始する時間。私は他の答えを選んだが、それはあなたが知っているので、それは質問に答えた;)ありがとう。 – natli

+0

@natli十分な公正、私は同じをやっただろう:)。 –

0
template<class T> 
    class Pointer 
    { 
     private: 
     T* pointer; 
     int* ref; 


    public: 
    Pointer():pointer(0), ref(0) 
    { 
    (*ref)++; 

    } 

    Pointer(T* value):pointer(value),reference(0) 
    { 
    (*ref)++; 

    } 

    Pointer(const pointer<T>& sp):pointer(sp.pointer),ref(sp.ref) 
    { 
     (*ref)++; 
    } 

    ~Pointer() 
    { 
    if(--(*ref)==0) 
    {delete pointer; 
     delete ref; 
    } 
    } 
    }; 

のようないくつかの演算子があります - >、*、=あなたがオーバーライドする必要があることを。

+0

は私にスマートなポインタを再実装したようです。 – hochl

+0

スレッドセーフではない再実装がそれほど難しいです。 –