C++ C++;检查未初始化的迭代器

C++ C++;检查未初始化的迭代器,c++,iterator,initialization,segmentation-fault,C++,Iterator,Initialization,Segmentation Fault,我浪费了大量的时间,因为我忘记初始化迭代器,然后尝试访问它们应该指向的数据。产生这种错误的唯一标志是运行时的分段错误。下面是一个例子: vector<Foo> V; //Uninitialized pointer: vector<Foo>::iterator it; //....loads of code later, attempt to access pointer that points to nothing (*it); //Segmentation fault!

我浪费了大量的时间,因为我忘记初始化迭代器,然后尝试访问它们应该指向的数据。产生这种错误的唯一标志是运行时的分段错误。下面是一个例子:

vector<Foo> V;
//Uninitialized pointer:
vector<Foo>::iterator it;
//....loads of code later, attempt to access pointer that points to nothing
(*it);
//Segmentation fault!
向量V; //未初始化指针: 向量::迭代器; //..加载代码后,尝试访问不指向任何内容的指针 (*资讯科技); //分割错误! 有没有一种标准技术可以在编译时自动执行这种检查?

在编译时?没有

我能想到几个运行时助手。首先是使用。第二个是设置一个sentinel向量,您可以使用它初始化迭代器

static vector<Foo> null_vector;
vector<Foo>::iterator it = null_vector.begin();
...
if (it == null_vector.begin())
静态向量null\u向量;
向量::迭代器it=null_vector.begin();
...
if(it==null_vector.begin())

我在实际代码中使用了一些技术。没有一个正是你想要的

首先,作为一种编程实践,我通常在需要的地方实例化一个变量,并在可以初始化它的时候实例化它。我从不实例化未初始化的变量

有时不可能在一个位置实例化和初始化。在这些情况下,我将使用类似Boost的
optional
,在需要使用它的地方,我将检查
optional
是否已设置


我经常发现,当不可能在一个位置实例化和初始化时,是因为某些函数的设计笨拙而笨拙,或者它试图做得太多。尝试将这些职责分解为多个函数,您可能会发现最初的问题——无法在一个位置初始化和实例化——消失了,生成了更干净的代码。

在C++14中,用户可以接受。(2013-04年通过)

所以这是真的:

vector<int>::iterator i1{};
vector<int>::iterator i2{};
assert(i1 == i2);
vector::迭代器i1{};
向量::迭代器i2{};
断言(i1==i2);
但这仍然是无效的:

vector<int>::iterator i1;
vector<int>::iterator i2;
assert(i1 == i2);
vector::迭代器i1;
向量::迭代器i2;
断言(i1==i2);

不过,我不确定哪些编译器支持这一点。

实用解决方案:将迭代器定义移过“…代码加载”位。使用惯用代码
for(auto-it=v.begin();…)
将“代码负载”减少到“一点点代码”如何?尽可能晚地声明迭代器,并在声明时初始化它。我很愿意,但迭代器包含在包装器中。我试图将实现
vector
从通用算法中抽象出来,因此我使用包装器的成员函数控制迭代器。想想看,在很多情况下,
都是可选的。我不能说我不同意你的答案,事实上我确实同意
可选的
,所以+1。@johndilling,有些人出于某种原因对
增强
有反感,所以我提供了一个替代方案。当然,这是有道理的。我也不能将Boost用于生产代码。为此,我开发了自己的
可选