c ++ map的.containsKey()方法

smi*_*ael 4 c++ templates

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

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

 using namespace std;
 map<string,XYclass> mymap;
 if (!contains(mymap,"key as string") ) cout << "key not found" << endl;
Run Code Online (Sandbox Code Playgroud)

在C++中,如果地图包含以下方式的键,则可以检查:

 m.find(str) != m.end();
Run Code Online (Sandbox Code Playgroud)

我想写一个泛型方法,如果一个键包含在一个映射中,它返回true.

到目前为止我有以下内容:

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

当我在map<string,int>跟随调用的情况下运行它时,将无法进行模板参数推导,contains(mymap,"key as string")因为"key as string"实际上是一个char数组.

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

怎么做得好?

Pio*_*cki 6

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

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();
}
Run Code Online (Sandbox Code Playgroud)

DEMO

您现在不需要显式指定类型模板参数.


确切地说,std::map总共有四种类型模板参数:

template <typename A, typename B, typename Cmp, typename Alloc>
inline bool contains(const std::map<A, B, Cmp, Alloc>& m
                   , const typename identity<A>::type& str);
Run Code Online (Sandbox Code Playgroud)


Pot*_*ter 5

不要将其硬编码为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(); }
Run Code Online (Sandbox Code Playgroud)

decltype如果您需要其他重载,说明符将执行 SFINAE 。