2012-01-28 10 views
0

これまでのところ、とても良い。しかし、いくつかの問題が生じました。別の奇妙なコンパイラエラー:未定義の参照を与えるテンプレート関数を呼び出す

error: undefined reference to `bool CheckMapForExistingEntry<std::string, int>(std::map<std::string, int, std::less<std::string>, std::allocator<std::pair<std::string const, int> > > const&, std::string const&)' 

はこれが起こっている場所を他の3件のインスタンスがあります。

const bool bppExists = CheckMapForExistingEntry< std::string, int >(mConfigValues, "bpp"); 

私は、次を得る:

まず第一に、私は次の呼び出し時にということです。

宣言

template < class Key, class Value > 
bool CheckMapForExistingEntry(const std::map< Key, Value >& map, const std::string& key); 

、ここで何が起こっているこのよう

template < class Key, class Value > 
bool CheckMapForExistingEntry(const std::map< Key, Value >& map, const std::string& key) 
{ 

    typename std::map< Key, Value >::iterator it = map.lower_bound(key); 

    bool keyExists = (it != map.end && !(map.key_comp() (key, it->first))); 

    if (keyExists) 
    { 
     return true; 
    } 

    return false; 
} 

定義:この関数は、以下のように見えますか?関数の宣言が含まれているヘッダーファイルが含まれていますが、まだ動作しません。 thisによれば、私はテンプレート引数の値を残して、ちょうど同じことをすることを拒否するkey_typeを渡すことになっています。例えば

CheckMapForExistingEntry<std::string>(someMap, "somekey"); //error 
+0

ソースファイル。宣言はヘッダーにあります。 – zeboidlund

答えて

2

はあなただけ簡単に宣言し、ヘッダーとソースファイル間のテンプレートの定義を分割することはできません。したがって、テンプレートは通常ヘッダーで定義されます。例えば、 "Why can templates only be implemented in the header file?"

また、あなたが明示的にこの場合、任意の型パラメータを提供する必要はありません。

CheckMapForExistingEntry(m, "x"); 

種類KeyValueが自動的にmapタイプから推定することができます。あなたの機能を大幅に短縮することができる

注、例えば:

template < class Key, class Value > 
bool contains(const std::map<Key, Value>& map, const std::string& key) { 
    return map.find(key) != map.end(); 
} 

また、関数がより多くの再利用可能な作り、keyパラメータの型を一般化できます。

+0

元のコードでは、検索文字列をキーと比較できるだけで、キータイプに変換することはできません。 –

+0

@Ben:しかし、 'lower_bound()'はパラメータとして 'key_type'を必要としますか? –

+0

あなたはもちろんそうです。 'std :: lower_bound'は匹敵する値を受け入れますが、' map'メンバ関数は正確にキー型を必要とします。 –

関連する問題