2012-01-28 49 views
0

到目前为止,这么好。但是,出现了一些问题。另一个奇怪的编译器错误:调用一个给出未定义参考的模板函数

首先,是当我调用如下

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

我得到如下:

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&)' 

在有些情况下这种情况正在发生的其他三个实例。功能如下所示:

宣言

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 2012-01-28 00:10:57

回答

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

原始代码只要求可以将搜索字符串与键进行比较,而不是将其转换为键类型。 – 2012-01-28 00:51:13

+0

@Ben:但'lower_bound()'需要一个'key_type'作为参数? – 2012-01-28 00:58:30

+0

你当然是对的。 'std :: lower_bound'接受任何可比较的值,但'map'成员函数完全需要密钥类型。 – 2012-01-28 01:14:56

相关问题