C++17中如何用const指针查找STL set中的非const指针?
问题解答:std::set存储非const指针时,查找const指针的优化方案
更好的实现方式
方案1:使用透明比较器修改std::set定义
C++14及以后支持透明比较器,将std::set的比较器改为std::less<>(而非默认的std::less<myclass*>),就能直接支持传入const myclass*进行查找,无需任何类型转换:
修改set的定义:
std::set<myclass*, std::less<>> myset;
之后原函数无需修改即可正常编译:
bool item_in_set( const myclass *ss ) { return myset.find( ss ) != myset.end(); }
这个方案的优势是保持了std::set的O(logn)查找效率,代码简洁且类型安全。
方案2:不修改set定义,用std::lower_bound实现类型安全查找
如果无法修改现有std::set的定义(比如代码中已大量依赖该set),可以用std::lower_bound配合自定义比较逻辑实现查找,避免const_cast:
#include <algorithm> // 引入std::lower_bound bool item_in_set( const myclass *ss ) { auto it = std::lower_bound(myset.begin(), myset.end(), ss, [](myclass* lhs, const myclass* rhs) { return lhs < rhs; // 遵循set的默认排序逻辑 }); return it != myset.end() && *it == ss; }
该方案同样保持O(logn)的查找效率,且完全避免了const_cast带来的风险。
const_cast方案的风险
你当前使用的const_cast虽然能正常运行,但存在以下隐患:
- 维护风险:后续开发者可能误以为需要通过转换后的指针修改对象,若原对象实际是const(比如是
const myclass的实例),修改操作会触发未定义行为。 - 代码可读性差:const_cast的存在会让其他开发者困惑——明明函数参数是const指针,为何要去掉const限定符?容易误导代码意图。
- 扩展性差:若后续将std::set的类型改为
std::set<const myclass*>,当前的const_cast会变成多余且无意义的操作,甚至可能引发编译警告。
内容的提问来源于stack exchange,提问作者xpapad
相关产品推荐
相关产品推荐

