c++ - 如何对复杂的模板化函数进行显式实例化?和相关的智能感知错误
问题描述
更新 1:将代码替换为独立构建的代码以使其更清晰
更新 2:部分修复了基于 @Jarod42 评论的实例化问题,但仍然失败
我有一些代码想要以不区分大小写的方式搜索带有字符串键的字典。完整代码如下。
所示代码编译、链接和工作,没有任何警告、错误或问题。
如果我取消注释显式实例化模板的行,那么我会得到
警告 C4667:'const std::_Tree_const_iterator>>> findKeyIC(const MyMap &,const std::wstring &)':未定义与强制实例化匹配的函数模板
此外,在调用 findKeyIC intellisense 的 FindNameMyMapIC 行中抱怨:
E0304 没有函数模板“findKeyIC”的实例与参数列表参数类型匹配:(const MyMap, const std::wstring)
我对 Intellisense 问题最感兴趣,但觉得显式实例化问题可能是相关的。
#include <boost/algorithm/string.hpp>
#include <map>
typedef std::map<std::wstring, int> MyMap;
const MyMap gMyMap = { { L"A", 0}, { L"B", 1 }, { L"C", 2 } };
// Cases insensitive comparison of two strings, return true if they match.
// Supports std:string variants and char*/wchar*.
template<class StrType>
inline bool StrIEquals(const StrType& str1, const StrType& str2)
{
return boost::iequals(str1, str2);
}
inline bool StrIEquals(const char* const& str1, const char* const& str2)
{
return (_stricmp(str1, str2) == 0);
}
inline bool StrIEquals(const wchar_t* const& str1, const wchar_t* const& str2)
{
return (_wcsicmp(str1, str2) == 0);
}
// Returns an iterator that refers to the location of an element in a map that has a key equivalent
// to a specified key using case insensitive comparison.
template <typename Key, typename Value, typename Reference, template<typename ...> class Container>
inline auto findKeyIC(const Container<Key, Value>& container, Reference const& key)
{
auto it = container.cbegin();
for (; it != container.cend(); ++it)
{
if (StrIEquals((const Key)it->first, (const Key)key))
return it;
}
return it;
}
// template const MyMap::const_iterator findKeyIC(const MyMap& container, const std::wstring& key);
int FindNameMyMapIC(const std::wstring& name)
{
auto it = findKeyIC(gMyMap, name);
if (it != gMyMap.cend())
{
return it->second;
}
return -1;
}
解决方案
我有这段代码来显式实例化模板:
MyMap::const_iterator findKeyIC(const MyMap& container, const std::wstring& key);
不,您声明非模板函数重载。
我认为智能感知受到“可变参数”容器的干扰,而std::map
不是。
如果可能,我会更改您的地图比较器以比较不区分大小写,因此您可以使用map::find
(对数查找而不是线性搜索)
否则,您可能会这样做:
// Returns an iterator that refers to the location of an element in a map that has a key equivalent
// to a specified key using case insensitive comparison.
template <typename Key, typename Container>
auto findKeyIC(const Container& container, Key const& key)
{
return std::find_if(container.cbegin(), container.cend(),
[&](const auto& p){ return StrIEquals(p.first, key); });
}
推荐阅读
- html - 无法理解为什么 CSS 不会从静态 HTML 页面复制到 Flask
- reactjs - FirebaseErrorr: Missing or insufficient permissions happens, When trying to get snapShot
- node.js - Receive empty Map when sending over Json to server
- javascript - Split a continous string (without space) with some length using JS
- javascript - json wihin multiple loop issue on basis of id
- python - What is the output of minAreaRect(contours)
- c# - 自动化纸牌游戏
- python-sphinx - Sphinx 无法导入模块依赖项
- sql - 如何在 Oracle 数据库中查找两条记录(两个不同的列)之间的时间间隔(以分钟为单位)
- python - 从嵌套列表中剥离文本并将内容保存到 csv 文件中