Это надуманный пример, но учтите следующее:
#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
?
Руководство по С ++ не раскрывайте, почему что-то подобное будет плохим вариантом использования.
Это не разрешено, потому что указатель не является массивом. Да, массив может распад в указатель, но, как следует из слова, такой распад теряет информацию. Результирующий указатель не эквивалентен массиву.
В отличие от преобразования массива в gsl::span
не теряет информации. Размер массива сохраняется, как и возможность его перебирать.
not_null
для указателя на объект, а не массив объектов. Как только unique_ptr
а также shared_ptr
не допускайте арифметику указателей. Если вы хотите использовать арифметику указателей для обработки массива, правильный ответ gsl::span
и его итераторы.
Других решений пока нет …