c++ - 为什么我们不应该对 gsl::not_null 使用指针运算?

标签 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不要解释为什么像这样的东西会是一个糟糕的用例。

最佳答案

这是不允许的,因为指针不是数组。是的,一个数组可以衰减成一个指针,但顾名思义,这种衰减会丢失信息。结果指针不等同于数组。

相比之下,将数组转换为 gsl::span 不会丢失任何信息。数组的大小保持不变,循环访问它的能力也是如此。

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

关于c++ - 为什么我们不应该对 gsl::not_null 使用指针运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38135616/

相关文章:

c++ - 使用指针,不调用重写的方法

c++ - 使用共享指针双重释放或损坏

Python - Pandas 导出到 csv 或 dat 文件删除无或 numpy.nan

ruby-on-rails - 未定义的方法 `collect' for nil :NilClass

sql - 查询值中的 NULL 在 MySQL 中导致 0.00

c++ - Emacs CEDET Semantic 没有自动完成 `this` 关键字。 (C++)

C++ map 插入和查找性能和存储开销

c++ - 忽略 C++ 中的字节顺序标记,从流中读取

c++ - 小型引用计数缓冲区类中的内存损坏

c++ - C++ 中的指针、释放和 vector