【发布时间】:2016-07-01 01:17:58
【问题描述】:
这是一个人为的例子,但请考虑以下几点:
#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 没有说明为什么这样的事情会是一个糟糕的用例。
【问题讨论】:
-
大概
not_null用于在任何情况下都不能为空的单个对象。可以编译时检查它们最初是否为空,但如果允许指针算术,则不能保证它们永远不会为空。所以他们不允许指针算术,并且在这个过程中引入了一个新的保证,即指针只能被重新分配;演员在这里作弊(重新引入 null 的可能性),但就这样吧。 -
你不应该在 C++ 中使用 c 成语,我就这么说吧。如果您想使用
++对它们进行操作,请坚持使用普通的 char * 数组/指针 -
@self:我认为 C++ 中的迭代器协议是指针算法的形式化和泛化,它并不是 C 特有的。
-
指南可能更希望您为数组构造一个
gsl::span,然后使用其中的迭代器。
标签: c++ pointers null pointer-arithmetic cpp-core-guidelines