set迭代器中的对象

时间:2011-01-12 18:55:11

标签: c++ iterator set

我可以在set迭代器中获取类的方法吗?

#include <iostream>
#include <string>
#include <set>
class student{
  public:
     student(std::string n){
        name=n;
     }
     void print(){
        std::cout << name << std::endl;
     }
     bool operator < (const student & s1){ return true;}
     bool operator = (const student & s1){ return true;}
  private:
     std::string name;
};
int main(){
  std::set<student> studs;
  studs.insert(student("name01"));
  studs.insert(student("name02"));
  std::set<student>::iterator it;
  for(it = studs.begin(); it != studs.end(); it++)
      (*it).print() ;
}

我收到此错误

students.cpp: In function ‘int main()’:  
students.cpp:22: error: passing ‘const student’ as ‘this’ argument of ‘void student::print()’ discards qualifiers
/usr/include/c++/4.2.1/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = student]’:
/usr/include/c++/4.2.1/bits/stl_tree.h:982:   instantiated from ‘std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = student, _Val = student, _KeyOfValue = std::_Identity<student>, _Compare = std::less<student>, _Alloc = std::allocator<student>]’
/usr/include/c++/4.2.1/bits/stl_set.h:307:   instantiated from ‘std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = student, _Compare = std::less<student>, _Alloc = std::allocator<student>]’
students.cpp:18:   instantiated from here
/usr/include/c++/4.2.1/bits/stl_function.h:227: error: passing ‘const student’ as ‘this’ argument of ‘bool student::operator<(const student&)’ discards qualifiers

     bool operator<(const student & s1) const { return true;}  
     bool operator==(const student & s1) const { return true;}  

现在工作!! O_o',

#include <iostream>
#include <string>
#include <set>
class student{
  public:
     student(std::string n){
        name=n;
     }
     void print() const {
        std::cout << name << std::endl;
     }
     bool operator<(const student & s1) const { return true;}
     bool operator==(const student & s1) const { return true;}
  private:
     std::string name;
};
int main(){
  std::set<student> studs;
  studs.insert(student("name01"));
  studs.insert(student("name02"));
  std::set<student>::iterator it;
  for(it = studs.begin(); it != studs.end(); it++)
      it->print() ;
}

5 个答案:

答案 0 :(得分:5)

您需要在const成员函数中添加print限定符:

void print() const
{
  std::cout << name << std::endl;
}

std::set中的对象必须const,因为它们被用作键。当对象(或引用)是常量时,您只能调用使用const限定符声明的该对象的成员函数。

您还需要const==运算符重载函数的<限定符。 (并且不要忘记如评论中所指出的那样将=更改为==。)

答案 1 :(得分:3)

是的,虽然it->print()更直观。

天真的世界观是迭代器有点像指针。正如here所解释的那样,还有更多内容。

  

最明显的迭代器形式是   指针:指针可以指向   数组中的元素,可以迭代   通过他们使用增量   运算符(++)。但其他形式的   迭代器存在。例如,每个   容器类型(如向量)具有   一个特定的迭代器类型   迭代它中的元素   有效的方式。

答案 2 :(得分:2)

  1. 您需要operator ==,而不是operator =。

  2. 您的运营商&lt;定义违反了std :: set的要求,并且与您的运算符&lt;不一致。也就是说,根据您的运营商&lt;,没有什么是等价的,但根据您的运营商==,一切都是平等的。运营商LT;应该定义一个反自转,传递和非对称(对于非等价值)的关系。

  3. 集合中的对象必然是const,因此要在这样的对象上调用函数,必须使用const限定符声明函数。具体来说,应该声明print()void print() const

  4. 类似地,运营商&lt;应该用const限定符声明。 std :: set要求运算符&lt;可以用const对象调用。另一个有效的选择是使运营商&lt;一个非成员函数,并按值(坏)或const引用(好)取两个对象。

  5. 虽然您的示例中不需要,但也应使用const限定符声明operator ==。

答案 3 :(得分:1)

像这样编写print()函数:

void print() const //<---- note this 'const'
{
        std::cout << name << std::endl;
}

现在您的代码应该可以使用了。 : - )

顺便说一句,右侧出现const关键字的函数称为const成员函数,因为它们不能更改类的任何成员数据。

请参阅此常见问题解答:[18.10] What is a "const member function"?

答案 4 :(得分:0)

#include <iostream>
#include <set>
using namespace std;
class Boxer{
    public:
        string name;
        int strength;
};
struct Comp{
    bool operator()(const Boxer& a, const Boxer& b){
        return a.strength > b.strength;
    }
};
int main(){
    Boxer boxer[3];
    boxer[0].name="uday", boxer[0].strength=23;
    boxer[1].name="manoj", boxer[1].strength=33;
    boxer[2].name="rajiv", boxer[2].strength=13;

    set< Boxer, Comp> s;
    s.insert(boxer[0]);
    s.insert(boxer[1]);
    s.insert(boxer[2]);
    set< Boxer, Comp>::iterator it = s.begin();
    Boxer b = *it;
    cout<<b.name;
    //result is Manoj

    return 0;
}