【问题标题】:When are two pointers comparable?两个指针什么时候可以比较?
【发布时间】:2014-03-18 06:31:50
【问题描述】:

关于比较两个指针的问题有很多,但我没有发现关于这两个类型是否可以比较指针。给定

A* a;
B* b;

我想知道表达式a @ b 是否有效,其中@==,!=,<,<,<=,>,>= 之一(我不知道注意nullptr_t 或任何其他可以隐式转换为指针的类型)。是A, B的时候吗

  • 相等?
  • 除了 cv-qualification 是否相等?
  • 在同一类层次结构中?
  • ...?

我在std::type_traits 中没有找到任何内容。我总是可以进行自己的 SFINAE 测试,但我正在寻找直接应用它们的规则。我想这对编译器来说会更容易,对吧?

编辑 再次澄清:我比较的是指针,而不是指向的对象。我想提前知道a @ b 何时会给出编译器错误,而不是它的值是什么(真或假或未指定)。

【问题讨论】:

    标签: c++ pointers typetraits comparison-operators


    【解决方案1】:

    C++ 标准

    5.9 关系运算符

    可以比较指向相同类型的对象或函数的指针(指针转换后), 结果定义如下:

    ——如果两个相同类型的指针 p 和 q 指向同一个对象或函数,或者都指向过去 相同数组的结尾,或者都为空,则 p=q 都产生 true 并且 pq 都 产生错误。

    ——如果两个相同类型的指针 p 和 q 指向不同的对象,它们不是相同的成员 同一数组或不同函数的对象或元素,或者如果其中只有一个为空,则结果 的 pq、p=q 未指定。

    ——如果两个指针指向同一个对象的非静态数据成员,或者指向子对象或数组元素 在此类成员中,递归地,指向后面声明的成员的指针比较大,前提是 两个成员具有相同的访问控制(第 11 条),并且他们的类不是联合。

    ——如果两个指针指向具有不同访问控制的同一对象的非静态数据成员 (第 11 条)结果未指定。

    ——如果两个指针指向同一个联合对象的非静态数据成员,它们比较相等(在 如有必要,转换为 void*)。如果两个指针指向同一个数组的元素或一个以外的元素 数组的末尾,下标高的对象的指针比较高。

    — 未指定其他指针比较。 §

    【讨论】:

    • 所以:表达式a @ b永远给出编译器错误,无论是否指定结果,对吧?
    • 是的;编译器不会抱怨。未定义的行为使它有机会以不明显的方式进行优化。
    • @Jonathan:“是的,编译器不会抱怨” - 不是真的......如果没有编译时错误,您无法比较指向不相关类型的指针。 “未定义的行为......” - Spook 描述 unspecified 行为 - 这基本上意味着编译器可能已将任何一个指向的对象放在更高的内存地址,而不是 Undefined 这意味着无法在没有崩溃或以其他方式破坏程序状态的情况下进行比较。
    • “指针...相同类型(指针转换后)可以比较”+1,但这是一半的问题,另一半是是否可以比较不同类型的指针。 ...
    • 它们必须兼容,即一个可以通过标准指针转换转换为另一个。
    【解决方案2】:

    这些比较运算符始终是“有效的”,因为您始终可以使用它们。但结果通常没有意义或有用。

    ==!= 基本上会告诉您ab 是否指的是同一个对象。如果a == b,那么改变*a会影响*b,反之亦然。

    ><>=<= 将告诉您内存地址相对于彼此的位置。通常这些信息与程序的功能无关,而且在大多数情况下是不可预测的。但是,如果您知道ab 指向同一数组的成员,那么您可能会想到一个可以使用它的示例。在这种情况下,a < b 会告诉您对象 *a 是否在数组中位于 *b 之前。

    【讨论】:

    • “那些比较运算符总是‘有效的’,因为你总是可以使用它们。” - 这不是真的...当AB 是不相关的类型时,您无法将A*B* 进行比较...您将收到编译器错误。
    猜你喜欢
    • 2011-11-20
    • 2018-02-07
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    相关资源
    最近更新 更多