我浪费了大量时间,因为我忘记初始化迭代器然后尝试访问他们应该指向的数据。产生此类错误的唯一标记是运行时的分段错误。这是一个例子:
vector<Foo> V;
//Uninitialized pointer:
vector<Foo>::iterator it;
//....loads of code later, attempt to access pointer that points to nothing
(*it);
//Segmentation fault!
在编译时是否有自动执行此类检查的标准技术?
答案 0 :(得分:2)
在编译时?否。
我可以想到几个运行时助手。首先是使用boost::optional
。第二种是设置一个可用于初始化迭代器的标记向量。
static vector<Foo> null_vector;
vector<Foo>::iterator it = null_vector.begin();
...
if (it == null_vector.begin())
答案 1 :(得分:2)
在C ++ 14中,compare value initialized iterators可以接受它。 (2013-04通过)
所以这是真的:
vector<int>::iterator i1{};
vector<int>::iterator i2{};
assert(i1 == i2);
但这仍然无效:
vector<int>::iterator i1;
vector<int>::iterator i2;
assert(i1 == i2);
我还不确定哪些编译器支持这个。
答案 2 :(得分:1)
我在实际代码中使用了一些技术。没有一个正是你想要的。
首先,作为编程实践,我通常会在接近需要的位置实例化一个变量,并在我初始化它时。我从未实例化过未初始化的变量。
有时无法在一个地方进行实例化和初始化。在这些情况下,我会使用像Boost optional
之类的东西,在我需要使用它时,我会检查是否已设置optional
。
我经常发现,当无法在一个地方进行实例化和初始化时,这是因为某些功能的设计笨拙且笨拙,或者它试图做太多。尝试将这些职责分解为多个功能,您可能会发现最初的问题 - 无法初始化&amp;在一个地方实例化 - 消失,产生更清晰的代码。