为什么 c++ 中的自定义比较器需要额外的 'const' 关键字
Why custom comparator for set in c++ requires extra 'const' keyword
我正在解决 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
这对我有用。
添加该额外关键字的原因是什么?
通过将 const
添加到该成员函数的末尾,您使其成为一个 const 成员函数,这意味着它不可能修改您的任何成员变量。因为调用 non-const 成员函数可以修改对象,所以如果对象是 const,则不能调用它。
std::set
的 erase 成员函数要求 operator() 是 const 以阻止它在您没有意识到的情况下修改其集合中的对象。
如果任何成员函数可以是 const,那么它应该是 const,就像您声明或作为参数接收的任何变量一样。
我正在解决 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
这对我有用。
添加该额外关键字的原因是什么?
通过将 const
添加到该成员函数的末尾,您使其成为一个 const 成员函数,这意味着它不可能修改您的任何成员变量。因为调用 non-const 成员函数可以修改对象,所以如果对象是 const,则不能调用它。
std::set
的 erase 成员函数要求 operator() 是 const 以阻止它在您没有意识到的情况下修改其集合中的对象。
如果任何成员函数可以是 const,那么它应该是 const,就像您声明或作为参数接收的任何变量一样。