使用std :: less和nullptr

时间:2015-03-02 13:30:58

标签: c++ c++11

以下代码段中的断言是否始终保持?

std::less<Object *> lessPtr;
Object * o = new Object();
assert(lessPtr (o, nullptr) == false);

2 个答案:

答案 0 :(得分:18)

简介

这个问题实际上归结为在一个操作数为nullptr的指针类型上使用 less-than 关系运算符是否会产生&#34; expect& #34; 结果;遗憾的是,情况并非如此。

结果是未指定

  

注意:请注意std::less保证总订单;意味着即使结果在使用函数对象时未指定,它也必须在每次调用时产生相同的未指定的值。


国际标准(N3337)说什么?

  

5.9p2 关系运算符 [expr.rel]

     
    

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

         
        
  • 如果同一类型的两个指针pq指向同一个对象或函数,或者两个指针都指向同一个数组的末尾,或者都是null,那么p<=qp>=q都会产生truep<qp>q都会产生false

  •     
  • 如果同一类型的两个指针pq指向不是同一对象的成员或同一数组的元素或不同函数的不同对象,或者仅指向其中一个为空,p<qp>qp<=qp>=q的结果未指定。

  •     
  • 如果两个指针指向同一对象的非静态数据成员,或者指向此类成员的子对象或数组元素,则递归地指向稍后声明的成员的指针比较更大,前提是两个成员具有相同的访问权限控制(第11条)并规定他们的班级不是工会。

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

  •     
  • 如果两个指针指向同一个union对象的非静态数据成员,则它们比较相等(如果需要,转换为void*之后)。如果两个指针指向同一个数组的元素或超出数组末尾的指针,则指向具有较高下标的对象的指针会比较高。

  •     
  • 未指定其他指针比较。

  •     
  

  

20.8.5p8 比较 [comparision]

     
    

对于模板greaterlessgreater_equalless_equal,任何指针类型的特化都会产生总顺序,即使内置运算符{{ 1}},<><=不会。

  

那么,标准的真正含义是什么?

>=


T * p = new T; T * q = nullptr; 的判决是什么?
由于p < qp没有指向同一个数组的不同元素(包括一个超过数组最后一个元素的元素),并且两者都没有指向非同一对象的静态数据成员;执行q(和p < q未指定时的结果。

p > q


bool a = p < q; // unspecified bool b = p < q; // unspecified assert (a == b); // can fire 怎么样?
但是,当使用std::less时,我们保证总订单 - 这实际上意味着以下断言不能触发( standard-20.8.5p8 )。

std::less

答案 1 :(得分:5)

不,未指定相对于任何非空指针的空指针的排序。

如果操作数&#34;指向不是同一对象的成员或同一数组的元素或不同函数的不同对象,或者只有其中一个为空&#34,则不指定比较运算符的结果。 34 ;.

std::less和朋友对此进行了扩展,以指定总订单,但不指定空指针在该订单中的位置。因此,它保证null将始终大于或小于任何给定的非空指针。但是它没有被指定为小于或大于所有非空指针。