Почему бы нам не использовать арифметику указателей с 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?
Руководство по С ++ не раскрывайте, почему что-то подобное будет плохим вариантом использования.

1

Решение

Это не разрешено, потому что указатель не является массивом. Да, массив может распад в указатель, но, как следует из слова, такой распад теряет информацию. Результирующий указатель не эквивалентен массиву.

В отличие от преобразования массива в gsl::span не теряет информации. Размер массива сохраняется, как и возможность его перебирать.

not_null для указателя на объект, а не массив объектов. Как только unique_ptr а также shared_ptr не допускайте арифметику указателей. Если вы хотите использовать арифметику указателей для обработки массива, правильный ответ gsl::span и его итераторы.

5

Другие решения

Других решений пока нет …