【问题标题】:Why am I getting a weird error message whenever I use sets?为什么每次使用集合时都会收到奇怪的错误消息?
【发布时间】:2021-10-15 07:51:43
【问题描述】:

现在我正在尝试学习 c++ STL,每次使用 set 或 multiset 数据结构时,我的 gcc 编译器都会返回一条我无法理解的错误消息,因为它太长(>40,000 个字符)。

这是我的程序:

#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;
}

这是我不得不删减的错误消息,因为它太长了,无法放入我的问题正文中:

    /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.
  • 是什么导致了这个错误?

  • 对于如何理解这么长的错误信息,您有什么建议吗?

【问题讨论】:

  • sort(si.begin(), si.end()); 不确定您希望这样做,因为multiset 已经排序。也可能是错误的原因。
  • @RetiredNinja 那么为什么一个看似简单的错误会产生这样的错误消息呢?这是编译器告诉我的吗?
  • 简单的答案是sort 需要随机访问迭代器,而multiset 只提供双向迭代器。如果您编写了像foo(int*) 这样的常规函数​​并将其传递给float*,您会得到一个简单的错误,基本上说您试图将一个方形钉放在一个圆孔中。更复杂的答案是标准库使用了很多模板,而你得到的错误是编译器告诉你基本相同的事情,但是它非常努力地试图通过尝试将它转换为某种东西来让你的方钉适合那个洞否则,它会适合多次,并向您展示每一步。

标签: c++ algorithm compiler-errors c++17 c++-standard-library


【解决方案1】:

是什么导致了这个错误?

错误来自于行

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

正如 @RetiredNinja 在 cmets 中已经提到的,std::sort 需要LegacyRandomAccessIterator std::multiset 有 LegacyBidirectionalIterator。 它们不一样,因此编译器错误。

话虽如此,std::multiset 已经排序,不需要通过任何排序函数对其进行排序。

std::multiset 是一个关联容器,其中包含一组已排序的 Key 类型的对象。与 set 不同,允许多个具有等效值的键。 使用键比较功能比较完成排序。搜索、插入和删除操作具有对数复杂度。


你对如何理解这么长的错误信息有什么建议吗?

从显示的错误信息来看,并没有直接提到,而是在我的MSVS with minimal example上编译:

#include <set>
#include <algorithm>

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

给我

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

它说,std::sort 正在寻找在迭代器类型中找不到的二进制 operator-(仅适用于 LegacyRandomAccessIterator)(即 LegacyBidirectionalIterator ) 你通过了,因此没有找到 std::sort 函数的重载。


另外,请注意以下几点:

【讨论】:

    猜你喜欢
    • 2017-06-25
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    相关资源
    最近更新 更多