C++ .containsKey()方法用于c++;地图

C++ .containsKey()方法用于c++;地图,c++,templates,C++,Templates,我想节省一些重复的工作,并编写一个模仿Java的函数 .containsKey()方法 基本上我想要这样的东西: using namespace std; map<string,XYclass> mymap; if (!contains(mymap,"key as string") ) cout << "key not found" << endl; 我想编写一个泛型方法,如果映射中包含键,该方法将返回true 到目前为止,我有以下几点: templa

我想节省一些重复的工作,并编写一个模仿Java的函数 .containsKey()方法

基本上我想要这样的东西:

 using namespace std;
 map<string,XYclass> mymap;
 if (!contains(mymap,"key as string") ) cout << "key not found" << endl;
我想编写一个泛型方法,如果映射中包含键,该方法将返回true

到目前为止,我有以下几点:

template<typename A, typename B> inline bool contains(const std::map< A, B > m, const A& str)
{
    return m.find(str) != m.end();
}
模板内联bool包含(const std::mapm,const A&str)
{
返回m.find(str)!=m.end();
}
当我在
map
上运行它时,它将无法执行模板参数推断,并调用
contains(mymap,“key as string”)
,因为“key as string”实际上是一个字符数组

当我进行显式实例化时(即通过使用以下调用
contains(mymap,“key as string”)
),函数工作正常


如何正确执行此操作?

可以使用以下标识技巧从模板参数推断中排除参数:

template <typename T>
struct identity { typedef T type; };

template <typename A, typename B>
inline bool contains(const std::map<A, B>& m
                   , const typename identity<A>::type& str)
{
    return m.find(str) != m.end();
}

我会将
contains()
函数声明为带有3个参数的模板:

template<typename Key, typename Value, typename Arg>
inline bool map_contains(const std::map< Key, Value > m, const Arg& value)
{
    return m.find(value) != m.end();
}
模板
内联布尔映射_包含(常量std::mapm,常量Arg&Value)
{
返回m.find(value)!=m.end();
}
注意,现在
Arg
必须隐式转换为
Key
。您可以轻松地删除此要求-只需调用
find()
,将
value
显式转换为
Key
类型即可


现场演示:。

不要硬编码到
std::map
。表达式
c.find(k)!=c、 end()
将适用于任何使用
find
方法返回迭代器的容器。该功能适用于任何此类类型

正如其他人所指出的,
std::map
为比较函数和节点分配器提供了额外的模板参数。原则上,列出它的所有参数违反了关注点的分离

template< typename container, typename key >
auto contains( container const & c, key const & k )
    -> decltype( c.find( k ) != c.end() )
    { return c.find( k ) != c.end(); }
模板
自动包含(容器常数和c、键常数和k)
->decltype(c.find(k)!=c.end())
{返回c.find(k)!=c.end();}

decltype
说明符执行SFINAE,以防您需要其他重载。

为什么要进行向下投票?这是一种不好的做法吗?使模板具有3个模板参数。另外,请将std::map作为参考传递,否则您可能必须在搜索ESMCVE时喝咖啡,否则就不会发生@斯米海尔很可能会投反对票,因为你的问题缺少一个简单的例子。在这里的问题中阅读有关MCVE的内容:实际上你可以使用
template<typename Key, typename Value, typename Arg>
inline bool map_contains(const std::map< Key, Value > m, const Arg& value)
{
    return m.find(value) != m.end();
}
template< typename container, typename key >
auto contains( container const & c, key const & k )
    -> decltype( c.find( k ) != c.end() )
    { return c.find( k ) != c.end(); }