STL集合的去引用迭代器

dereferencing iterator of STL set

本文关键字:引用 迭代器 集合 STL      更新时间:2023-10-16

我在继承STL集时遇到问题(我想):

这里是一流的:

class Prime : public set<A> {
private:
  // private data members.
public:
  // C'tor...
  void printParticularA(const int& id);
}

这是A类:

class A : public List<B>{  
private:  
  // data members.  
  int id;
public:  
  // C'tor  
  A(const A& copy) : List<B>(copy), //copy data members  
     { // validate data and throw exceptions if needed. };
  bool operator< (const A& rhs) const{  
    return id < rhs.id;  
  }
  void printReport() const {  
    for(const B& item : *this){ item.print(); }
  }
}

现在问题来了。在下一个函数中,我想打印集合中的特定a对象:

void Prime::printParticularA(const int& id) {
  find(AFinder(id))->printReport();
}

我也试过这个:

void Prime::printParticularA(const int& id) {
  *(find(AFinder(id))).printReport();
}

注意:假设类B有print()方法
注2:AFinder是一个只使用id数据制作伪a对象的类。

问题是,当'find'找到对象时,它会返回const_iterator(因为集合中的每个对象都是const),当我取消引用它时,我会得到对象的副本(??),但其中的B列表是空的
"->"版本也会发生这种情况。

现在我知道该集合不允许我更改对象,但我不打算更改对象(正如您在printReport成员函数的声明中所看到的)。

我很感激在这方面的任何帮助!

编辑:谢谢大家,你们帮了我很多,尤其是学会了不该做什么。
我解决了这个问题,但它不在集合、列表中,也不在我的任何课程中
我的错误是理解了给我的问题(是的,这是我的家庭作业,我对c++还是个新手)
如果你觉得我浪费了你的时间,我很抱歉
我希望我能从你所有的经验中学习,有一天能帮助别人
简而言之,谢谢!!:)

您的代码到处都是一团糟。这个问题看起来并没有直接与集合或迭代器联系在一起,而是做了一些一般的坏事。

首先,让你的op<const并永远删除复制ctor——库存ctor会正常工作。使用集合的内部查找来搜索并查看是否找到项目。

所有这些都可能会让你描述的问题消失,如果没有,发布一个完整的可编译的例子,并附上你所看到和期望的正确文本。

您的代码确实违反了C++的许多规则。你为什么不试试这样的smth:

#include <iostream>
#include <list>
#include <map>
using namespace std;
class SimpleInt {
public:  
  int data_;
  SimpleInt(const int data): data_(data) {};
  void print() const {cout << data_ << " ";};
};
template <typename T>
class A {  
private:  
  // private data members.  
public:  
  list<T> list_of_B_; // this is for simlicity. Make getters as you need
  const int id_; // delete it or copy to map. You sholdn't change it.
  A(int id) : list_of_B_(), id_(id) {} 
  A(const A<T>& copy) : list_of_B_(copy.list_of_B_), id_(copy.id_) {} //copy data members  
  A(A<T>&& copy) : list_of_B_(::std::move(copy.list_of_B_)), id_(copy.id_) {} //move data members  
  void printReport() const {  
    for(const T& item : list_of_B_){ item.print(); }
  }
};
template <typename T>
class Prime {
private:
  // private data members.
public:
  // The main difference with your source
  map<int, T> map_of_A_; // this is for simlicity. Make getters as you need
  // C'tor...
  void printParticularA(const int& id) {
    auto it = map_of_A_.find(id);
    if (it != map_of_A_.end())
      it->second.printReport();
  }
};
int _tmain(int argc, _TCHAR* argv[])
{
  typedef A<SimpleInt> ASimpled;
  Prime<ASimpled> prime;
  ASimpled a(1);
  a.list_of_B_.push_back(SimleInt(1));
  a.list_of_B_.push_back(SimleInt(2));
  a.list_of_B_.push_back(SimleInt(3));
  ASimpled b(2);
  b.list_of_B_.push_back(SimleInt(10));
  b.list_of_B_.push_back(SimleInt(20));
  b.list_of_B_.push_back(SimleInt(30));
  prime.map_of_A_.insert(make_pair(a.id_, a));
  prime.map_of_A_.insert(make_pair(b.id_, b));
  prime.printParticularA(2);
return 0;
}

虽然您还没有包括List的实现,但问题很可能存在。更确切地说,Listbegin()end()成员函数可能被破坏。很可能它们返回的值是相同的(或无效的),导致基于范围的for循环什么都不做。这当然是基于您的set::find正在返回一个有效的迭代器,而不是结束迭代器。

以下示例是对您问题中的代码的修改。它使用std::list而不是List,并且不使用AFinder,因为您还没有包含它的代码

#include <set>
#include <list>
#include <iostream>
struct B
{
    int id_;
    explicit B(int id) : id_(id) {}
    void print() const
    {
        std::cout << "B::id = " << id_ << std::endl;
    }
};
class A : public std::list<B>
{
public:
    explicit A(int id) : id_(id) {}
    bool operator<(const A& rhs) const
    {
        return id_ < rhs.id_;
    }
    bool operator==(const A& other) const
    {
        return id_ == other.id_;
    }
    void printReport() const
    {  
        for(auto& item : *this)
        {
            item.print();
        }
    }
private:  
    // data members.  
    int id_;
};

class Prime : public std::set<A>
{
public:
    void printParticularA(const int& id)
    {
        std::cout << "finding " << id << std::endl;
        auto el = find(A(id));
        if(el == cend())
        {
            std::cout << "not found" << std::endl;
        }
        else
        {
            find(A(id))->printReport();
        }
        std::cout << "done finding " << id << std::endl;
    }
};

int main()
{
    Prime p;
    A   a1(1);
    a1.push_back(B(1));
    a1.push_back(B(2));
    a1.push_back(B(3));
    p.insert(a1);
    A   a2(2);
    a2.push_back(B(4));
    a2.push_back(B(5));
    a2.push_back(B(6));
    p.insert(a2);
    p.printParticularA(1);
    p.printParticularA(2);
    // doesn't exit
    p.printParticularA(3);
}

这将产生以下输出。

查找1
B: :id=1
B: :id=2
B: :id=3
已完成查找1
查找2
B: :id=4
B: :id=5
B: :id=6
完成查找2
查找3
未找到
完成查找3