Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.containsKey() method for c++ map

Tags:

c++

templates

I want to save some repeating work and write a function that mimicks Java .containsKey() method.

Basically I would like to have something like this:

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

In C++ one can check, if a map contains key in following way:

 m.find(str) != m.end();

I want to write a generic method that returns true if a key is contained in a map.

So far I have following:

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

which will fail to do template argument deduction, when I run it on a map<string,int> with following call contains(mymap,"key as string"), as "key as string" is actually a char array.

Function works fine when I do explicit instantiation (i.e. by using following call contains<string,int>(mymap,"key as string"))

How to do it properly?

like image 865
smihael Avatar asked Aug 17 '15 17:08

smihael


People also ask

What is use of keySet () in MAP?

keySet() method in Java is used to create a set out of the key elements contained in the hash map. It basically returns a set view of the keys or we can create a new set and store the key elements in them. Parameters: The method does not take any parameter.

What is the significant difference between containsKey () and get ()?

get(Object) does explicitly warn about the subtle differences between Map. get(Object) and Map. containsKey(Object) : If this map permits null values, then a return value of null does not necessarily indicate that the map contains no mapping for the key; it's also possible that the map explicitly maps the key to null .

What will be the time complexity to perform containsKey () operation in maps?

The time complexity of containsKey has changed in JDK-1.8, as others mentioned it is O(1) in ideal cases.

How do I extract a value from a map?

HashMap. get() method of HashMap class is used to retrieve or fetch the value mapped by a particular key mentioned in the parameter. It returns NULL when the map contains no such mapping for the key.


2 Answers

One can exclude parameters from template argument deduction with the below identity trick:

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

DEMO

You don't need to specify type template arguments explicitly now.


To be precise, std::map has the total of four type template parameters:

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);
like image 91
Piotr Skotnicki Avatar answered Sep 25 '22 12:09

Piotr Skotnicki


Don't hard-code it to std::map. The expression c.find( k ) != c.end() will work for any container with a find method returning an iterator. The function is applicable to any such types.

As others have noted, std::map has additional template parameters for the comparison function and the node allocator. In principle, listing all its parameters violates the separation of concerns.

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

The decltype specifier performs SFINAE, in case you want other overloads.

like image 36
Potatoswatter Avatar answered Sep 23 '22 12:09

Potatoswatter