为什么我们不应该使用gsl :: not_null的指针算法?

时间:2016-07-01 01:17:59

标签: c++ pointers null pointer-arithmetic cpp-core-guidelines

这是一个人为的例子,但请考虑以下因素:

#include <iostream>
#include "gsl.h"

int main(){

  //object or array that I'd like to iterate over one byte at a time
  char array[] = {'a','b','c','d','e','f'};

  //create a C-like iterator
  char* it = &array[0];

  //use pointer arithmetic to process
  std::cout << *it << std::endl; it++;
  std::cout << *it << std::endl; it++;
  std::cout << *it << std::endl; it++;
}

为安全起见,我想用not_null标记指针 然而,这无法编译。

#include "gsl.h"
#include <iostream>

int main(){

  //object or array that I'd like to iterate over one byte at a time
  char array[] = {'a','b','c','d','e','f'};

  //create a C-like iterator
  gsl::not_null<char*> it = &array[0];

  //use pointer arithmetic to process
  std::cout << *it << std::endl; it++;
  std::cout << *it << std::endl; it++;
  std::cout << *it << std::endl; it++;
}

not_null的课程外

// unwanted operators...pointers only point to single objects!
// TODO ensure all arithmetic ops on this type are unavailable
not_null<T>& operator++() = delete;
not_null<T>& operator--() = delete;
not_null<T> operator++(int) = delete;
not_null<T> operator--(int) = delete;
not_null<T>& operator+(size_t) = delete;
not_null<T>& operator+=(size_t) = delete;
not_null<T>& operator-(size_t) = delete;
not_null<T>& operator-=(size_t) = delete;

我很困惑他们为什么要这样做 为什么我的指针不能改变其值?

特别是当它很容易到处时:

it = &array[0];
it = static_cast<char*>(it)+1;

我错过了not_null的要点吗? C++ Guidelines没有说明为什么这样的事情会成为一个糟糕的用例。

1 个答案:

答案 0 :(得分:6)

不允许这样做,因为指针不是数组。是的,一个数组可以衰减成一个指针,但正如这个词所暗示的那样,这种衰变会丢失信息。结果指针不等于数组。

相比之下,将数组转换为gsl::span则不会丢失任何信息。保持数组的大小,以及迭代它的能力。

not_null用于指向对象的指针,而不是对象数组。就像unique_ptrshared_ptr不允许指针算术一样。如果要使用指针算法处理数组,则正确的答案是gsl::span及其迭代器。