首页 > 解决方案 > 当应用于不相关的指针时,std::less 如何比 < 更安全?

问题描述

我发现我应该使用std::less来比较我的对象,以便能够比较不相关的指针(来自不同的序列),因为<如果在那些不相关的指针上使用关系运算符,则只使用关系运算符就会产生 UB。

输出:

-1
 1  
 0
-1
 1

标签: c++pointerscomparison

解决方案


怎么可能std::less比 更安全<

因为标准是这样说的。

我是说内部结构。

在所有 x64 和大多数现代架构std::less::operator()上只是对内置运算符的简单包装,<或者将指针转换为uinptr_t然后进行比较。

C++ 旨在适用于各种硬件架构,因此大概有一些架构(历史?,古老?,奇怪?)并非所有数据地址都(容易)可比较。在那些架构上,操作员<将无法工作,而std::less需要实现工作方式。


作为旁注,您没有在示例中比较指针


我应该使用std::less而不是<

对于指向(可能)不同对象或不同数组中的指针,是的,否则如果您<在这种情况下使用,则您有未定义的行为。对于其他任何事情都没有。std::less当您需要将比较器功能提供给其他一些功能(例如std::sort)时,它最有用。

例如:

int a{}, b{}
int* p_a = &a;
int* p_aa = &a;
int* p_b = &b;

p_a < p_b; // technically Undefined Behavior, use std::less instead:
std::less<>{}(p_a, p_b);

p_a < p_a; // ok
p_a < p_aa; // ok
int arr1[10]{}
int* p1_1 = &arr1[0];
int* p1_2 = &arr1[5];

int arr2[10]{};
int* p2_1 = &arr2[0];
int* p2_2 = &arr2[5];

p1_1 < p2_1; // technically Undefined Behavior, use std::less instead:
std::less<>{}(p_1_1, p_2_1);

p1_1 < p1_2; // ok
p2_1 < p2_2; // ok
char str[] = "hello";
char* str_end = str + strlen(str);

for (char* p = str; p < str_end; ++p) // ok
    // ...

用于其他任何用途<

int a{}, b{};
a < b; // ok

std::string s1{}, s2{};
s1 < s2; // ok

推荐阅读