独占指针 < 0 或者小于运算符是做什么用的?

9

我正在处理一些不是我写的代码。我有以下语句:

// p is type of std::unique_ptr<uint8_t[]>
if (p < 0) { /* throw an exception */ }

在这个上下文中,“p < 0”是什么意思呢?在文档页面上,我认为我的情况是“16) y < nullptr”,其中“0”是“nullptr”。但它具体是做什么呢?

1
基于x64中,内核范围的规范指针具有设置了上位比特,这可能是一种(愚蠢的硬编码)检查指针是否属于内核空间的方法 - 如果下面的答案是正确的话,那么不是。 - Michael Chourdakis
1
在WINAPI中,p==-1是一个无效的句柄。由于2^64是一个非常巨大的数字,任何明智的p都应该是正数。因此,p<0检查WINAPI的无效句柄并不是一个好的代码实现。 - ALX23z
@OP:您能否稍微澄清一下这段代码的使用情况?它是在Linux还是Windows上使用的?指针的值是否与某些WINAPI代码相关?我认为如果您澄清了这一点,上面的评论可能就是好答案了。 - walnut
@ALX23z 但是 WINAPI 句柄应该是 uint8_t* 类型(或者甚至是 uint8_t 数组类型)吗?我认为它们是 void*,不是吗? - walnut
@walnut,它们不是void*,它们有宏HANDLE_PTR或类似的东西,基本上是long*,如果我没记错的话。 - ALX23z
3个回答

2

unique_ptr < 0 OR what does less than operator do?

这将匹配cppreference上的重载(11):operator<(const unique_ptr&, nullptr_t);。0会隐式转换为std::nullptr_t。根据文档,结果是std::less<unique_ptr<T,D>::pointer>()(x.get(), nullptr)

结果在实现上是未定义的,但在大多数系统上都是无条件为false。假设在一个奇特的系统中,null没有二进制表示为0,则结果可能为true。

I believe my case is 16)

(16)与另一种情况相同:0 > unique_ptr。结果相同。


@alteredinstance,0不被“视为”nullptr(或取决于您对“视为”的理解)。0隐式转换为std::nullptr_t - eerorika
@alteredinstance 转换不能反过来进行。int x = nullptr 是不合法的。 - eerorika
抱歉,我重新措辞了我的问题,省略了“反过来”的部分。那不是我想说的意思。 - alteredinstance
2
std::nullptr_t旨在与任何空指针常量一起使用,而不仅仅是nullptr。 0(例如0L)也是空指针常量,因此可以使用它们来创建std::nullptr_t - eerorika
更准确地说,我们有auto p = std::make_unique<uint8_t[]>(pos_number);然后我们改变数据p.get(); 那么现在它对你来说完全没有任何意义,是吗? - Sagid
显示剩余4条评论

2

请检查您的代码中是否有重载 operator < 的情况。这似乎是 (p < 0)true 的唯一可能性。

例如:

bool operator< (const std::unique_ptr<uint8_t[]>&, int) { return true; }

int main() {
    std::unique_ptr<uint8_t[]> p;
    std::cout << (p < 0) << std::endl;
}

输出:

1

实时演示

否则,正如其他人所说,0会隐式转换为std::nullptr_t,这将选择bool operator<(const unique_ptr<T, D>& x, nullptr_t)重载,该重载将调用std::less(p, 0),它将返回false(即使在具有-1指针值的Windows上也是如此)。


它不一定会返回 false。这要么是实现定义的,要么是未指定的(我不确定)。但我同意它可能在大多数(全部?)实现中返回 false。另请参见 @eerorika 的答案。 - walnut

0

这个表达式与此模板运算符匹配(0被转换为nullptr):

template <class T, class D>
bool operator<(const unique_ptr<T, D>& x, nullptr_t);

这返回的是std::less<unique_ptr<T,D>::pointer>()(p.get(), nullptr),其永远为假(因为std::less是一个严格排序函数)(演示)。

它并不总是返回“false”。它是否这样做要么是实现定义的,要么是未指定的。尽管在大多数(全部?)当前实现中,它可能总是返回“false”。 - walnut
@walnut 除非问题明确要求从标准的角度回答(例如通过 [tag:language-lawyer] 标签),否则我会从实际应用的角度回答。所有 std::less 的实际实现都返回 false - YSC
没问题,我只是不认为你的解释("as std::less is a strict order functor")有说服力。它可以是一种严格的序列,而不必返回 false。实际原因可能是零指针值由最低可能地址表示或类似的东西。 - walnut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接