C++中Set/Map的KeyEqual是否等价于std::memcmp?模板类内可查询吗?
Set/Map容器中KeyEqual谓词与std::memcmp的等价性及模板内省问题
问题拆解
- 如何判断Set或Map容器使用的KeyEqual谓词,功能上是否等价于
std::memcmp? - 在模板类中,能否查询或内省KeyEqual的这类行为特性?
等价性判定示例
- 算术标量类型:KeyEqual的比较逻辑等价于直接对比内存位模式,和
std::memcmp的功能完全一致。 - 空终止字符串指针:KeyEqual不会仅对比指针地址的位模式,此时判断相等需要调用
std::strcmp,和std::memcmp的行为完全不同。
模板类内省的实现方式
C++标准没有提供直接内省KeyEqual谓词特性的原生机制——毕竟KeyEqual是可完全自定义的仿函数/函数对象,其行为由用户决定,编译器无法自动推导它是否等价于std::memcmp。
若要实现这类判断,只能通过模板特化或标签分发手动标记:
- 针对默认
std::equal_to<T>这类标准谓词,根据Key类型做特化:- 当Key是算术标量时,标记其等价于
std::memcmp; - 当Key是字符串指针时,标记其不等价。
- 当Key是算术标量时,标记其等价于
- 自定义KeyEqual时,需要手动为其添加对应的特性标签,供模板类识别。
示例代码如下:
#include <type_traits> #include <cstring> // 默认特质:不等价于memcmp template<typename KeyEqual, typename Key> struct is_memcmp_equivalent : std::false_type {}; // 特化:std::equal_to<T> + 算术标量类型 template<typename T> struct is_memcmp_equivalent<std::equal_to<T>, T> : std::bool_constant<std::is_arithmetic_v<T>> {}; // 自定义字符串指针相等谓词 struct StrPtrEqual { bool operator()(const char* a, const char* b) const { return std::strcmp(a, b) == 0; } }; // 为自定义谓词特化特质 template<> struct is_memcmp_equivalent<StrPtrEqual, const char*> : std::false_type {}; // 使用示例 int main() { // 算术标量的默认谓词,等价于memcmp,结果为true static_assert(is_memcmp_equivalent<std::equal_to<int>, int>::value); // 字符串指针的自定义谓词,不等价于memcmp,结果为false static_assert(!is_memcmp_equivalent<StrPtrEqual, const char*>::value); return 0; }
内容的提问来源于stack exchange,提问作者John Yates
相关产品推荐
相关产品推荐

