C++17/20下定义带自定义比较器的std::set编译错误,C++14运行正常
错误成因
- 报错核心是静态断言提示
comparison object must be invocable as const,C++17及之后的标准对关联容器的比较器提出了更严格的要求:比较操作必须可以在const的比较器对象上调用。 - C14标准下的STL实现没有加入对应的合法性检查,所以你的代码可以正常编译运行,到C17之后STL加入了这个静态检查,不符合要求的代码就会编译失败。
- 你自定义的
Pointer_comp比较类的operator()没有加const修饰符,属于非const成员函数,无法在const的比较器对象上被调用,因此触发了静态断言报错。
修复方法
只需要给比较类的operator()加上const修饰符即可,修改后的完整代码如下:
#include <bits/stdc++.h> using namespace std; template<class T> class Pointer_comp { public: // 尾部加const表示该成员函数可以在const对象上调用 bool operator()(const T* p1, const T* p2) const { return std::less<T>()(*p1, *p2); } }; int main() { string *str1 = new string("fbvf"), *str2 = new string("adkva"), *str3 = new string("nljkm"); set<string*, Pointer_comp<string>> strs({str1, str2, str3}); // 业务逻辑代码... // 注意:不要忘记释放new出来的string对象,避免内存泄漏 for (auto p : strs) delete p; return 0; }
- 额外注意:如果你的业务场景中可能出现空指针,需要在
operator()中额外加入空指针判断逻辑,避免解引用空指针引发未定义行为。 - 该修改兼容C++11及之后所有标准版本,不需要单独处理不同标准的适配。
内容的提问来源于stack exchange,提问作者Farzan
相关产品推荐
相关产品推荐

