Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何检查迭代器是否已初始化?_C++_Iterator - Fatal编程技术网

C++ 如何检查迭代器是否已初始化?

C++ 如何检查迭代器是否已初始化?,c++,iterator,C++,Iterator,如果我对迭代器使用默认构造函数,如何检查它是否在以后分配 对于指针,我可以这样做: int *p = NULL; /// some code if ( NULL == p ) { // do stuff } 如何对迭代器执行上述操作? 有可能吗 #include <iostream> #include <list> int main () { std::list<int>::iterator it; if ( NULL == it ) /

如果我对迭代器使用默认构造函数,如何检查它是否在以后分配

对于指针,我可以这样做:

int *p = NULL;
/// some code
if ( NULL == p ) {
  // do stuff
}
如何对迭代器执行上述操作? 有可能吗

#include <iostream>
#include <list>

int main ()
{
    std::list<int>::iterator it;

  if ( NULL == it ) // this fails
  {
      std::cout<<"do stuff" << std::endl;
  }
}
#包括
#包括
int main()
{
std::list::迭代器;
if(NULL==it)//此操作失败
{

std::cout你不能。你能做的就是和列表末尾进行比较

it != mylist.end();

在C++中,未初始化的局部变量可以包含任何值,即它包含简单的垃圾。这意味着,不能通过一些定义良好的值来检查它,以确定变量是否未初始化。 不仅如此,如果变量未初始化且您写入以下内容:

if ( NULL == it ) // this fails

然后它调用未定义的行为。

也许在创建迭代器之后,您应该始终指定一个预定义的值,如NULL。稍后您可以轻松地检查NULL。
这将使您的代码更具可移植性,因为您将不依赖于未初始化变量在开始时采用的起始值。

大多数迭代器没有任何全局特殊值,就像所有指针都可以为空一样。不过,通常情况下,您将使用特定容器,如果每个容器保留一个迭代器,然后可以使用
end()
作为哨兵值:

std::list<int> mylist;
std::list<int>::iterator it = mylist.end();

/* do stuff */

if (it == mylist.end()) { ... }
尽管我也不确定比较两个无效迭代器是否定义得很好(如果这两个迭代器都无效)。

if(std::list::iterator()==it)
但我怀疑…有可能,一个有效的迭代器可以通过比较。 最好避免这些情况。如果不可能,用指针存储迭代器

 std::auto_ptr<std::list<int>::iterator> it;
std::自动下载它;

我在当前的标准(c++03)中找到了这一点。24.1 p 5告诉我们:

正如指向数组的常规指针保证存在 指针值指向数组的最后一个元素,因此对于任何 迭代器类型有一个迭代器值,它指向最后一个 元素。这些值被称为 超过结束值。迭代器i的值
*i
被定义为可取消引用。库从不假定 超过端点的值是可取消引用的。迭代器也可以具有 不与任何容器关联的奇异值。[示例: 在声明未初始化指针
x
(与
int*x;
一样)之后,
x
必须始终假定指针具有单数值。] 大多数表达式的结果对于奇异值是未定义的 唯一的例外是将非奇异值赋值给迭代器 它包含一个奇异值。在这种情况下,奇异值为 以与任何其他值相同的方式覆盖。可取消引用的值 它们总是非单数的

(强调矿山)


所以答案是:不,这是不可能的。

这个问题已经在中讨论过了。其精髓是默认构造函数将迭代器初始化为一个奇异值,唯一可添加的操作是为其分配另一个迭代器值。特别是,不可能查询这种统一迭代器的值或者。因此,将迭代器初始化为特定容器的特定值是一种很好的编程实践,然后可以对其进行测试。

我能想到的最好的方法是

#include <utility>
#include <map>
#include <typeinfo>
#include <string>



namespace nulliterators {

typedef std::map<std::string, void*> nullcntT;
nullcntT nullcontainers;

template<class containerT>
typename containerT::iterator iterator() {
  containerT* newcnt = new containerT();
  std::string cnttypename = typeid(*newcnt).name();
  nullcntT::iterator i = nullcontainers.find(cnttypename);
  if (i==nullcontainers.end()) {
    nullcontainers.insert(make_pair(cnttypename, newcnt));
    return newcnt->end();
   }else{
    delete newcnt;
    return (static_cast<containerT*>(i->second))->end();
  }
}

}
template<class containerT>
typename containerT::iterator nulliterator() { return nulliterators::iterator<containerT>(); }


#include <list>
#include <iostream>


int main(){

  std::list<int>::iterator nullinitized = nulliterator< std::list<int> >();
  std::list<int> somelist;
  std::list<int>::iterator initialized = somelist.end();

  if (nullinitized == nulliterator< std::list<int> >())
    std::cout << "nullinitized == nulliterator< std::list<int> >()\n";  //true
   else
    std::cout << "nullinitized != nulliterator< std::list<int> >()\n";

  if (initialized == nulliterator< std::list<int> >())
    std::cout << "initialized == nulliterator< std::list<int> >()\n";
   else
    std::cout << "initialized != nulliterator< std::list<int> >()\n";  //true

  return 0;
}
#包括
#包括
#包括
#包括
命名空间空迭代器{
typedef std::map nullcntT;
nullcntT nullcontainers;
模板
typename containerT::迭代器迭代器(){
containerT*newcnt=newcontainert();
std::string cnttypename=typeid(*newcnt).name();
nullcntT::迭代器i=nullcontainers.find(cnttypename);
if(i==nullcontainers.end()){
nullcontainers.insert(make_pair(cnttypename,newcnt));
返回newcnt->end();
}否则{
删除newcnt;
return(static_cast(i->second))->end();
}
}
}
模板
typename containerT::iterator nulliterator(){返回nulliterators::iterator();}
#包括
#包括
int main(){
std::list::iterator nullinitized=nulliterator();
std::list somelist;
std::list::iterator initialized=somelist.end();
if(nullinitized==nulliterator())
std::cout())

据我所知,您必须始终初始化迭代器,最简单的方法是使它们等于“container”。end() 在某些情况下,它看起来是可行的,我们在使用VC6的代码中遇到了一些问题,并停止了使用VC2010。请看这个使用g++编译的示例,其中它适用于向量,但不适用于映射:

# Test iterator init, compile with: g++ test-iterator.cpp -o test-iterator
#include <iostream>
#include <vector>
#include <map>

int main()
{
    std::vector<int> vec;
    std::vector<int>::iterator it;

    if (it != vec.end())
    {
            std::cout << "vector inside!" << std::endl;
    }
    else
    {
            std::cout << "vector outside!" << std::endl;
    }

    std::map<int, int> mp;
    std::map<int, int>::iterator itMap;

    if (itMap != mp.end())
    {
            std::cout << "map inside!" << std::endl;
    }
    else
    {
            std::cout << "map outside!" << std::endl;
    }

    return 0;
}
#测试迭代器init,使用:g++Test-iterator.cpp-o测试迭代器编译
#包括
#包括
#包括
int main()
{
std::vec;
std::vector::it迭代器;
如果(it!=vec.end())
{

std::cout由于迭代器没有默认值(就像指针没有空值),在我需要
对象::迭代器
的公共默认值的情况下(在创建任何实际对象之前),我创建一个伪静态变量,并使用其
::end()
作为默认值

更新:这仅适用于发行版,因为在调试中(或使用
\u HAS\u ITERATOR\u debuging=1
),比较运算符检查两个迭代器是否指向同一对象/容器

例如,对于
vector
,我会:

class A
{
public :
    A() :  myIterator1(dummyVector.end()), myIterator2(dummyVector.end()) {}
    // needed iterators
    vector<int>::iterator myIterator1;
    vector<int>::iterator myIterator2;

    static const vector<int> dummyVector;
}

#define  IT_NULL A::dummyObject.end()

void maint() {
    A::dummyObject = vector<int>(); // initialize the Null iterator

    A a;
    if(a.myIterator1 == IT_NULL) cout << "Iterator not yet initialized";
}
A类
{
公众:
A():myIterator1(dummyVector.end()),myIterator2(dummyVector.end()){}
//需要的迭代器
向量::迭代器myIterator1;
向量::迭代器myIterator2;
静态常数向量dummyVector;
}
#定义它\u NULL A::dummyObject.end()
void maint(){
A::dummyObject=vector();//初始化空迭代器
A A;

如果(a.myIterator1==IT_NULL)不能我使用了以下解决方案:

const MyList_t::const_iterator NullIterator(NULL);
const_iterator MyList_t::MyIterator;
然后可以进行检查:

if (NullIterator != MyIterator) {}

据我所知,没有普遍的保证
const MyList_t::const_iterator NullIterator(NULL);
const_iterator MyList_t::MyIterator;
if (NullIterator != MyIterator) {}