为什么在 c++ 中设置自定义比较器需要额外的“const”;关键词

发布于 2025-01-15 19:36:47 字数 3324 浏览 1 评论 0原文

我正在解决 leetcode OJ 上的一个问题,其中我必须使用自定义比较器来在 C++ 中设置。

typedef pair<pair<int,int>,int> ppi;

class comp
{
    public:
    bool operator()(const ppi & p1, const ppi & p2)
    {
        if(p1.first.first == p2.first.first)
        {
            if(p1.first.second == p2.first.second) return p1.second > p2.second;
            else return p1.first.second > p2.first.second;
        }
        else
            return p1.first.first > p2.first.first;
    }
};

当我尝试从集合中删除一个元素时,这给了我一个错误,如下所示:

set<ppi, comp> customStack;
.
.
.
customStack.erase({{currentFrequency, currentAddress},val});

错误:

In file included from prog_joined.cpp:1:
In file included from ./precompiled/headers.h:50:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/map:60:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:779:4: error: static_assert failed due to requirement 'is_invocable_v<const comp &, const std::pair<std::pair<int, int>, int> &, const std::pair<std::pair<int, int>, int> &>' "comparison object must be invocable as const"
          static_assert(
          ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:1997:31: note: in instantiation of member function 'std::_Rb_tree<std::pair<std::pair<int, int>, int>, std::pair<std::pair<int, int>, int>, std::_Identity<std::pair<std::pair<int, int>, int>>, comp, std::allocator<std::pair<std::pair<int, int>, int>>>::_S_key' requested here
          if (_M_impl._M_key_compare(_S_key(__x), __k))
                                     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:2534:38: note: in instantiation of member function 'std::_Rb_tree<std::pair<std::pair<int, int>, int>, std::pair<std::pair<int, int>, int>, std::_Identity<std::pair<std::pair<int, int>, int>>, comp, std::allocator<std::pair<std::pair<int, int>, int>>>::equal_range' requested here
      pair<iterator, iterator> __p = equal_range(__x);
                                     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:685:21: note: in instantiation of member function 'std::_Rb_tree<std::pair<std::pair<int, int>, int>, std::pair<std::pair<int, int>, int>, std::_Identity<std::pair<std::pair<int, int>, int>>, comp, std::allocator<std::pair<std::pair<int, int>, int>>>::erase' requested here
      { return _M_t.erase(__x); }
                    ^
Line 39: Char 25: note: in instantiation of member function 'std::set<std::pair<std::pair<int, int>, int>, comp, std::allocator<std::pair<std::pair<int, int>, int>>>::erase' requested here
            customStack.erase({{currentFrequency, currentAddress},val});
                        ^
1 error generated.

在比较器中添加“const”之后(第4行):

class comp
{
    public:
    bool operator()(const ppi & p1, const ppi & p2)const

这对我有用。

添加额外关键字的原因是什么?

I am solving a problem on leetcode OJ where i had to use a custom comparator for set in C++.

typedef pair<pair<int,int>,int> ppi;

class comp
{
    public:
    bool operator()(const ppi & p1, const ppi & p2)
    {
        if(p1.first.first == p2.first.first)
        {
            if(p1.first.second == p2.first.second) return p1.second > p2.second;
            else return p1.first.second > p2.first.second;
        }
        else
            return p1.first.first > p2.first.first;
    }
};

this is giving me an error when i am trying to delete an element from the set, which looks like:

set<ppi, comp> customStack;
.
.
.
customStack.erase({{currentFrequency, currentAddress},val});

error:

In file included from prog_joined.cpp:1:
In file included from ./precompiled/headers.h:50:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/map:60:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:779:4: error: static_assert failed due to requirement 'is_invocable_v<const comp &, const std::pair<std::pair<int, int>, int> &, const std::pair<std::pair<int, int>, int> &>' "comparison object must be invocable as const"
          static_assert(
          ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:1997:31: note: in instantiation of member function 'std::_Rb_tree<std::pair<std::pair<int, int>, int>, std::pair<std::pair<int, int>, int>, std::_Identity<std::pair<std::pair<int, int>, int>>, comp, std::allocator<std::pair<std::pair<int, int>, int>>>::_S_key' requested here
          if (_M_impl._M_key_compare(_S_key(__x), __k))
                                     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:2534:38: note: in instantiation of member function 'std::_Rb_tree<std::pair<std::pair<int, int>, int>, std::pair<std::pair<int, int>, int>, std::_Identity<std::pair<std::pair<int, int>, int>>, comp, std::allocator<std::pair<std::pair<int, int>, int>>>::equal_range' requested here
      pair<iterator, iterator> __p = equal_range(__x);
                                     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_set.h:685:21: note: in instantiation of member function 'std::_Rb_tree<std::pair<std::pair<int, int>, int>, std::pair<std::pair<int, int>, int>, std::_Identity<std::pair<std::pair<int, int>, int>>, comp, std::allocator<std::pair<std::pair<int, int>, int>>>::erase' requested here
      { return _M_t.erase(__x); }
                    ^
Line 39: Char 25: note: in instantiation of member function 'std::set<std::pair<std::pair<int, int>, int>, comp, std::allocator<std::pair<std::pair<int, int>, int>>>::erase' requested here
            customStack.erase({{currentFrequency, currentAddress},val});
                        ^
1 error generated.

after added 'const' in the comparator (line 4):

class comp
{
    public:
    bool operator()(const ppi & p1, const ppi & p2)const

this worked for me.

What is the reason for adding that extra keyword?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

叹沉浮 2025-01-22 19:36:47

通过将 const 添加到该成员函数的末尾,您将使其成为 const 成员函数,这意味着它不可能修改任何成员变量。因为调用非常量成员函数可能会修改对象,所以如果对象是 const,则无法调用它。

std::set 的擦除成员函数要求operator() 为const,以阻止它在您没有意识到的情况下修改集合中的对象。

如果任何成员函数可以是 const,那么它也应该是 const,就像您声明或作为参数传入的任何变量一样。

By adding that const to the end of that member function you're making it a const member function, meaning that it cannot possibly modify any of your member variables. Because calling a non-const member function could modify the object, you can't call it if the object is const.

std::set's erase member function requires that operator() be const to stop it from modifying the object's in their set without you realizing.

If any member function can be const then it should be const, just like any variables you declare or take in as arguments.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文