M.Cesar
M.Cesar

Reputation: 91

Creating an iterator to a map in a class template

I have this class template which contains a map as following:

template<class K, class V>
class interval_map {

private:
    std::map<K,V> m_map;    
}

And I want to have a function that adds values to the maps and checks whether the key already exists or not so I am trying to do this using iterator :

void add_elements_test2 ( K const& key,V const& val)
{             
    std::make_pair<typename std::map<K,V>::iterator,bool>x;  
    x= m_map.insert(std::make_pair(key,val));
    if(x.second = false)
    {
        cout<<"Key alreads exists "<<endl;
    }
}

but I get this error when I create the operator:

std::make_pair<typename std::map<K,V>::iterator,bool>x;

Is this is a correct way?

Upvotes: 0

Views: 620

Answers (3)

abe
abe

Reputation: 504

I wrote this answer so that you don't hate template classes in the future. There are 2 scenarios you need to consider, and I have listed them both in the code below. Let me know if you have any questions, the comments are detailed.

Scenario 1, add_elements_test2 is defined inside the class

template<class K, class V>
class interval_map {
private:
    std::map<K,V> m_map;    

    // This is fine because the K and V types are in the same scope for the map, and add_elements_test2
    void add_elements_test2 ( K const& key,V const& val)
    {
        // Use auto here to simplify your life a little
        auto x = m_map.insert(std::make_pair(key,val)); // actual type is std::pair<K, bool>
        if(x.second == false)
        {
            cout<<"Key already exists "<<endl;
        }
    }
};

Scenario 2, add_elements_test2 is defined outside the class

template<class K, class V>
class interval_map {
private:
    std::map<K,V> m_map;    

    void add_elements_test2 ( K const& key,V const& val);
};

// need another template
template<class K, class V>
// need to template interval_map, this could cause headaches if you did not realize this is a templated class
void interval_map<K, V>::add_elements_test2 ( K const& key,V const& val)
{
    // Use auto here to simplify your life a little
    auto x = m_map.insert(std::make_pair(key,val)); // actual type is std::pair<K, bool>
    if(x.second == false)
    {
        cout<<"Key already exists "<<endl;
    }
}

Essentially, your mistake with x is the type definition.

// pair is in the utility header
std::pair<K, bool> x= m_map.insert(std::make_pair(key,val));

Upvotes: -1

Jarod42
Jarod42

Reputation: 217135

Simply use auto:

auto x = m_map.insert(std::make_pair(key, val));
if (!x.second)
{
    cout << "Key already exists" << endl;
}

Note: the type you want is pair

std::pair<typename std::map<K, V>::iterator, bool>

std::make_pair is an utility function to create std::pair.

Upvotes: 1

NathanOliver
NathanOliver

Reputation: 180500

std::make_pair<typename std::map<K,V>::iterator,bool>x;  

It not correct the correct way to declare a std::pair. If you want to declare a std::pair for the return of insert then you need

std::pair<typename std::map<K,V>::iterator,bool> x;

And now x has the correct type. std::make_pair is a function that is used to construct a std::pair and you pass it the variables to make the pair from.

Instead of having to type all this though you can simply use auto like

auto x = m_map.insert(std::make_pair(key,val));
//...

Now x has the correct type and you do a lot less typing.


You also have a typo in

if(x.second = false)

In the above you are doing assignment, not comparison. Since you are setting the value to false the if statement will never run as it will always evaluate to false. You need

if(x.second == false)

Upvotes: 1

Related Questions