我有几个std::map<some_type, some_other_type>
,我正在尝试编写下面展示的函数模板Lookup
。
当键为指针或标量时,函数模板可以正常工作,但是如果键是std::string
则会出现问题。
#include <iostream>
#include <map>
// Usage :
// bool valueisinmap = Lookup(themap, thekey, thevalue);
template <typename TK, typename TV>
bool Lookup(std::map<TK, TV>& map, TK key, TV& value)
{
auto it = map.find(key);
if (it != map.end())
{
value = it->second;
return true;
}
else
{
return false;
}
}
int main()
{
std::map<std::string, std::string> m;
m.insert(std::make_pair("2", "two"));
std::string x;
std::string key = "2";
if (Lookup(m, key, x))
std::cout << "OK\n";
if (Lookup(m, "2", x)) // problem here
std::cout << "OK\n";
}
我理解为什么
Lookup(m, "2", x)
无法编译,因为"2"
的类型不是std::string
,但是否有办法编写函数模板,使我既可以使用Lookup(m, "2", x)
,也可以使用Lookup(m, key, x)
,其中key
为std::string
?如果可以,这就引发了第二个问题:
bool Lookup(std::map<TK, TV>& map, TK key, TV& value)
key
是按值传递的,如果其类型是 std::string
,则会进行拷贝。有没有一种方法可以通过引用(或某些 C++14 的黑科技)来传递 key
,并且仍然能够使用 Lookup(m, "2", x)
?
key
的值将是什么?std::type_identity_t<TK>
不是一个空结构体吗? - Ton van den Heuvelstd::type_identity
只有一个成员类型,实际上,std::type_identity_t<TK>
和TK
是相同的,它们都是引用类型TK
,除了使模板参数不可推断外,然后TK
将仅从第一个参数推导,避免了类型推断中的歧义。 - songyuanyao