另一个奇怪的编译错误:调用一个模板化函数,它给出了未定义的引用

时间:2012-01-28 00:06:30

标签: c++ function templates map

到目前为止,这么好。但是,出现了一些问题。

首先,当我呼叫以下内容时:

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;
}

因此,这里发生了什么?我有包含头文件,其中包含函数的声明,但它仍然无法正常工作。根据{{​​3}},我应该忽略模板参数的值,然后传递key_type,但是它也拒绝工作。

例如:

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

1 个答案:

答案 0 :(得分:2)

您不仅可以轻松地在头文件和源文件之间拆分模板的声明和定义;因此模板通常在标题中定义。参见例如"Why can templates only be implemented in the header file?"

在这种情况下,您也不需要显式提供任何类型参数:

CheckMapForExistingEntry(m, "x");

可以从Key类型自动推断出Valuemap类型。

请注意,您的功能可以大大缩短,例如:

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

此外,您可以概括key参数的类型,使该函数更具可重用性。