So far, so good. However, a few issues have arisen.
First and foremost, is that when I call the following:
const bool bppExists = CheckMapForExistingEntry< std::string, int >( mConfigValues, "bpp" );
I get the following:
error: undefined reference to `bool CheckMapForExistingEntry(std::map, std::allocator > > const&, std::string const&)'
There are three other instances of where this is happening. The function looks as follows:
Declaration
template < class Key, class Value >
bool CheckMapForExistingEntry( const std::map< Key, Value >& map, const std::string& key );
Definition
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;
}
Thus, what is happening here? I have the header file included which contains the declaration of the function, and yet it still doesn't work. According to this, I'm supposed to leave out the value of the template argument and just pass the key_type
, however that refuses to work as well.
For example:
CheckMapForExistingEntry< std::string >( someMap, "somekey" ); //error
Answer
You can't just easily split the declaration and the definition of templates between header and source file; thus templates are usually defined in headers. See e.g. "Why can templates only be implemented in the header file?".
Also you don't need to explicitly provide any type parameters in this case:
CheckMapForExistingEntry(m, "x");
The types Key
and Value
can be automatically deduced from the map
type.
Note that your function can be significantly shortened, e.g.:
template < class Key, class Value >
bool contains(const std::map& map, const std::string& key) {
return map.find(key) != map.end();
}
Additionally you could generalize the type of the key
parameter, making the function more reusable.
No comments:
Post a Comment