Tuesday, 29 August 2017

c++ - Another strange compiler error: calling a templated function which gives undefined referenes





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

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...