Dies ist ein konstruiertes Beispiel, aber die folgenden Punkte beachten:Warum sollten wir Zeigerarithmetik nicht mit gsl :: not_null verwenden?
#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++;
}
Zur Sicherheit würde ich den Zeiger mit not_null
markieren möchte.
Dies kompiliert jedoch nicht.
#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++;
}
Eine Ausnahme von not_null
‚s Klasse:
// 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;
Ich bin verwirrt, warum sie dies getan haben.
Warum kann ich keinen Zeiger haben, der seinen Wert ändert?
Vor allem, wenn es einfach ist, zu umgehen:
it = &array[0];
it = static_cast<char*>(it)+1;
Fehle ich den Punkt der not_null
?
Die C++ Guidelines decken nicht, warum so etwas ein schlechter Anwendungsfall wäre.
Vermutlich ist 'not_null' für einzelne Objekte gedacht, die unter keinen Umständen null sein können. Es ist möglich, die Zeit zu kompilieren, um zu überprüfen, dass sie anfangs nicht Null sind, aber wenn Zeigerarithmetik erlaubt war, konnten Sie nicht garantieren, dass sie nie null sein würden. Sie verbieten also Zeigerarithmetik und führen dabei eine neue Garantie ein, dass der Zeiger nur neu zugewiesen werden kann; Die Besetzung betrügt hier (Wiedereinführung der Möglichkeit von Null), aber so sei es. – ShadowRanger
Sie sollten keine C-Idiome in C++ verwenden, ich sage es einfach. Bleiben Sie bei einfachen char * -Arrays/Zeigern, wenn Sie sie mit '++' –
@self bearbeiten wollen: Ich würde das Iterator-Protokoll in C++ als Formalisierung und Verallgemeinerung der Zeigerarithmetik ansehen, es ist nicht besonders C-spezifisch. – ShadowRanger