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



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

#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++指南并没有解释为什么这样的用例会很糟糕。

这是不允许的,因为指针不是数组。是的,数组可以衰变为指针,但顾名思义,这种衰变会丢失信息。生成的指针不等于数组。

相反,将数组转换为gsl::span不会丢失任何信息。数组的大小保持不变,遍历数组的能力也保持不变。

not_null用于指向对象的指针,而不是对象数组。就像unique_ptrshared_ptr不允许指针算术一样。如果你想用指针算术来处理数组,正确的答案是gsl::span和它的迭代器。

相关内容

  • 没有找到相关文章

最新更新