1

Right now I'm trying to learn the c++ STL & every time I use the set or multiset data structure, my gcc compiler, returns an error message that I can't understand because it's so long (>40,000 characters).

Here is my program:

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n, m;
    int h, t;
    cin >> n >> m;
    multiset<int> si;
    for (int i = 0; i < n; i++) 
    {
        cin >> h;
        si.insert(h);
    }
    sort(si.begin(), si.end());

    vector<int>vi;
    for (int i = 0; i < m; i++)
    {
        cin >> t;
        vi.push_back(t);
    }

    sort(vi.begin(), vi.end());
    int count = 0;
    for (int i = 0; i < n; i++) 
    {
        auto it = upper_bound(si.begin(), si.end(), vi[i]);
        for (auto elem : si)
        {
            if (it != si.end() and (vi[i] == *it || vi[i] == elem))
            {
                count++;
            }
        }
    }
    cout << count;
}

This is the error message that I had to cut down because it was too long to fit in the body of my question:

    /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/valarray:1173:1: note: 
      candidate template ignored: could not match 'valarray' against
      '_Rb_tree_const_iterator'
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/valarray:1155:5: note: 
      expanded from macro '_DEFINE_BINARY_OPERATOR'
    operator _Op(const valarray<_Tp>& __v, const _Tp& __t...
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/valarray:1173:1: note: 
      candidate template ignored: could not match 'valarray' against
      '_Rb_tree_const_iterator'
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/valarray:1165:5: note: 
      expanded from macro '_DEFINE_BINARY_OPERATOR'
    operator _Op(const _Tp& __t, const valarray<_Tp>& __v...
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/complex:451:5: note: 
      candidate function template not viable: requires single argument
      '__x', but 2 arguments were provided
    operator-(const complex<_Tp>& __x)
    ^
2 errors generated.
  • What is producing this error?

  • And do you any advice on how to comprehend such long error messages?

JeJo
  • 30,635
  • 6
  • 49
  • 88
  • `sort(si.begin(), si.end());` Not sure what you expect this to do since `multiset` is already sorted. Likely the cause of the error as well. – Retired Ninja Aug 11 '21 at 21:17
  • @RetiredNinja so why is a seemingly simple mistake producing an error message like this? Is this what the compiler was telling me? – Lyon-Dalipsy Aug 11 '21 at 21:24
  • The simple answer is that `sort` requires random access iterators but `multiset` only provides bidirectional iterators. If you wrote a regular function like `foo(int*)` and passed it a `float*` you'd get a simple error that basically says you tried to put a square peg in a round hole. The more complicated answer is that the standard library uses a lot of templates, and the error you got is the compiler telling you basically the same thing, but it tried very hard to make your square peg fit that hole by trying to convert it to something else that would fit many times and showed you every step. – Retired Ninja Aug 11 '21 at 21:51

1 Answers1

2

What is producing this error?

The error is from the line

sort(si.begin(), si.end());

As @RetiredNinja already has mentioned in the comments, the std::sort require the LegacyRandomAccessIterator and the std::multiset has LegacyBidirectionalIterator. They are not the same, hence the compiler error.

That being said, the std::multiset is already sorted, and no need for sorting it via any sort function.

std::multiset is an associative container that contains a sorted set of objects of type Key. Unlike set, multiple keys with equivalent values are allowed. Sorting is done using the key comparison function Compare. Search, insertion, and removal operations have logarithmic complexity.


Do you any advice on how to comprehend such long error messages?

From the shown error messages, it is not directly mentioned but compiling on my MSVS with minimal example:

#include <set>
#include <algorithm>

int main()
{
    std::multiset<int> si;
    std::sort(si.begin(), si.end());
}

gives me

error C2676: binary '-': 'const std::_Tree_unchecked_const_iterator<std::_Tree_val<std::_Tree_simple_types<int>>,std::_Iterator_base0>'
does not define this operator or a conversion to a type acceptable to the predefined operator
.........
........
error C2672: '_Sort_unchecked': no matching overloaded function found

It says, that the std::sort was looking for the binary operator- (available only for LegacyRandomAccessIterator) which could not find in the iterator type (i.e. LegacyBidirectionalIterator) you passed, hence there is no overload for the std::sort function found.


Also, note that followings:

JeJo
  • 30,635
  • 6
  • 49
  • 88