2017-02-02 17 views
4

を使用してのconstと非constのは非会員機能のためのコードの重複を減らす:は、私は2つの以下の機能を持っているテンプレート

Thing* find_thing_by_name(const String & name, Map<String,Thing*> & thing_map) 
{ 
    auto it = thing_map.find(name); 
    return it->second; 
} 
const Thing* find_thing_by_name(const String & name, const Map<String,Thing*> & thing_map) 
{ 
    auto it = thing_map.find(name); 
    return it->second; 
} 

これは私が解決したい問題のためだけの簡単な例です。

これらの関数はまったく同じ本体ですが、私のマップのconstバージョンとnon constバージョンの両方を処理する必要があります。この問題はconstキャストを使ったメンバー関数で処理されていますが、これらは非メンバ関数なので、テンプレートを使用してこの問題を解決したいと思います。コードの重複を減らすテンプレート化された関数を作成するにはどうすればよいですか?私はどこから始めたらいいかわからない。

+0

あなたの質問に直接答えるのではなく、単に「m_AllowChange」のような「Thing」にメンバー変数を追加し、それがfalseかtrueかによって、「Thing」に変更を許可することができます。しかし、もちろん、これの利便性は、「Thing」クラスがどれほど複雑かにかかっています。 – macroland

答えて

4

次のことが可能です。その後、

template <typename MAP> 
auto find_thing_by_name(const String & name, MAP & thing_map) 
{ 
    auto it = thing_map.find(name); 
    return it->second; 
} 

String s = ...; 
Map<String,Thing*> nonconst_m = ...; 
const Map<String,Thing*> const_m = ...; 
find_thing_by_name(s, nonconst_m); // MAP is deduced as Map<String,Thing*> 
            // thing_map's type is Map<String,Thing*>& 
find_thing_by_name(s, const_m); // MAP is deduced as const Map<String,Thing*> 
            // thing_map's type is const Map<String,Thing*>& 
+0

うわー、本当に簡単ですか?コンパイラは、型MAPにfindメソッドがあることをどのように知っていますか? – Dillydill123

+1

@ Dillydill123それはあなた次第です。あなたが何かを渡すと、それをサポートしていないので、コンパイルエラーが発生します。 – songyuanyao

0

私はあなたが問題をoverthoughtと思います。両方のパラメータのバリエーション(const参照と非const参照を渡した)の両方のメソッドの同じコードは、メソッド内でこのパラメータを変更しないことを意味します(そのメソッドのconstメソッドのみを呼び出します)。そうでなければ、同じコードはconst参照のためにコンパイルされません。これは、const map & thing_mapの仮パラメータを使用して、メソッド内で常にconst以外のthing_map実パラメータを渡すことができるため、このメソッドの1つのバージョンのみを実装する必要があることを意味します。 実際の例では、2番目の例ではconst Thing *を返す必要はありません.2番目の例はまだThing *ではないからです。 は、これが私のsujestionです:

Thing* find_thing_by_name(const String & name, const Map<String,Thing*> & thing_map) 
{ 
    auto it = thing_map.find(name); 
    return it->second; 
} 

またはあなただけのこのバージョンを実装する事オブジェクトへのアクセスを制限したい場合:

その後、
const Thing* find_thing_by_name(const String & name, const Map<String,Thing*> & thing_map) 
{ 
    auto it = thing_map.find(name); 
    return it->second; 
} 

バリアントのいずれかのこのよう使用することができます

... 
const Map<String, Thing *> constMapObj; 
const Map<String, Thing *> nonConstMapObj; 
.... 
auto res1 = find_thing_by_name(someKey, constMapObj); 
auto res2 = find_thing_by_name(someOtherKey, nonConstMapObj); 
+0

このようにオーバーロードすることはできません。コンパイラは、パラメータに基づいてどのコンパイラを呼び出すかを決定します。あなたのパラメータは両方の過負荷で同じですので、これはあいまいです。 – greatwolf

+0

私は過負荷を意味するわけではなく、実装は1つだけです。上の答えは同じです。ただ、そのパラメータはsymantically constメソッドの非const参照を通っています。 – user3414895

関連する問題