Home > Software engineering >  error code C2676 binary '==': 'std::pair<std::string,int>'does not define
error code C2676 binary '==': 'std::pair<std::string,int>'does not define

Time:05-27

Does anyone know why the following code doesn't work? the error occurs because of the code -> auto it = find(output.begin(), output.end(), resource);


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>

using namespace std;

int main()
{
    vector<pair<string, int> >output;
    string resource;
    int quantity;
    bool first = true;
    while (true)
    {
        cin >> resource;
        if (resource == "stop")
            break;
        cin >> quantity;
        if (first)
        {
            first = false;
            output.push_back(pair<string, int>(resource, quantity));
            continue;
        }
        auto it = find(output.begin(), output.end(), resource);
        if (it != output.end())
            it->second  = quantity;
        else
            output.push_back(pair<string, int>(resource, quantity));
    }

    for (size_t i = 0;i<output.size();i  )
    {
        cout << output[i].first << " -> " << output[i].second << endl;
    }

    return 0;
}

why does thi happend and how to fix it?

CodePudding user response:

The problem is this statement

auto it = find(output.begin(), output.end(), resource);

the algorithm std::find uses objects of the type std::pair<std::string, int> (according to the definition of the vector output to which it is applied) to compare them with the object resource or the type std::string and there is no such an equality operator for objects of these types.

Instead use the std::find_if algorithm For example

auto it = find_if( output.begin(), output.end(), 
                   [&]( const auto &p ) { return p.first == resource; } );

Also instead of the container std::vector<std::string, int> consider using containers std::map<std::string, int> or std::unordered_map<std::string, int>.

Pay attention to that actually this if statement

    if (first)
    {
        first = false;
        output.push_back(pair<string, int>(resource, quantity));
        continue;
    }

is redundant. You could at once use this code snippet without the above if statement

    auto it = find(output.begin(), output.end(), resource);
    if (it != output.end())
        it->second  = quantity;
    else
        output.push_back(pair<string, int>(resource, quantity));

provided that you will call the algorithm std::find_if as shown in the beginning of the answer.

CodePudding user response:

You're looking for a string in a vector of pairs.

That doesn't work; find needs to be able to compare the elements of the thing it's looking in (i.e., pair<string, int>) with what you're looking for.

You're using the wrong container type, anyways. You clearly want to store key-value pairs, with the keys being strings, and the values ints. So, use a map.

#include <unordered_map>
…
std::map<std::string, int> output;
…
// if the resource is not yet in the map, accessing it using  [] will create it,
// and assign the default value for an int, 0, to it.
int& value = output[ressource];
value  = quantity;

A std::map or std::unordered_map does what you do: it contains pairs of keys and values, but it's way cleverer organized than your vector; you don't have to walk through all the map to find out whether an element is in there.

  • Related