2011-05-18 110 views
3

我有下面这段代码:
const成员函数

class Test{ 
private: 
    int id; 
public: 
    Test(int v):id(v) {} 
    int getId() { return id;};   // however,I change this method signature 
              int getId() const { return id;}; 
              and all the errors gone 
}; 

struct compare{ 
    bool operator()(const Test& t1, const Test& t2){ 
    return t1.getId() < t2.getId();  // got error here 
    } 
}; 

int main(int argc, char *argv[]){ 
    set<Test, compare> s; 
    Test str[] = {Test(1), Test(2), Test(3)}; 
    for (int i = 0; i < 3; ++i){ 
    s.insert(str[i]); 
    } 
    for (set<Test>::iterator it = s.begin(); it != s.end(); ++it){ 
    cout << it->getId() << "\n";  // got error here 
    }  
    return EXIT_SUCCESS; 
} 

我得到这个错误,当我调用的方法的getId()与代码:

passing `const Test' as `this' argument of `int Test::getId()' discards qualifiers 

我不知道为什么我需要const getId()方法来修复该错误?谢谢

回答

10
bool operator()(const Test& t1, const Test& t2) 

您的操作员需要参考const Test对象。您只能通过对const限定类型的引用来调用const合格的成员函数。

set<Test>::iterator it = s.begin() 

std::set的元素是不可变的:您无法更改它们。因此,迭代器到std::set始终是const限定类型的对象。

+0

关于“迭代器一个std ::组总是到对象的常量限定类型。”:即在C的任何版本指定被++标准或这取决于标准库开发人员? – 2011-05-18 04:03:36

+1

@Eugen:它在标准的第23.2.4p6节中指定(在C++ 0x中,编号可能在早期版本中有所不同)。 – 2011-05-18 04:11:17

+0

@Eugen:在(C++ 0x FDIS)中指定23.2.4 p5关联容器中的键是不可变的&p6'对于关联容器,其中 的值类型与键类型相同,迭代器和const_iterator都是常量迭代器“。 – Xeo 2011-05-18 04:14:41

2
const Test& t1 

使t1不变,也就是说,它不能通过该引用进行更改。现在,您对该对象调用的任何函数都可能改变其内部状态 - const不允许!

这是怎么解决的?只需将不会改变内部状态的函数标记为const!这意味着,它们可以在const对象/引用/指针上调用。
这就是为什么你需要constgetId函数,以确保你不会改变任何内部状态。

int getId() const { return id;}; 

编辑:当然,这同样适用于std::set,但我不会去,作为其他的答案已经这样做了。

3

set::iterator只给出const访问元素,变化可能会影响集合中元素的相对顺序 - 不变的,它需要保护(也就是说,如果你在设置更改元素,可能会损坏的假设排序设置中的元素,以及未来的查找,插入等将不会如预期的那样可靠地工作)。因此,只有const成员函数可以通过iterator对元素访问进行调用。

这有点令人困惑,因为对于其他一些容器,const_iteratoriterator的选择决定了授予的访问权限。

1

你只能在const对象上调用const成员函数。

set<Test>::iterator it = s.begin(); 

返回一个const对象,所以你只能调用这个对象的const类型的成员函数。

+0

真的,'* it'返回一个const对象。迭代器本身不是'const'。 – 2011-05-18 04:12:08

0

运算符()在其参数列表中有const Test&对象,因此当您通过const对象调用时,需要使用const限定符声明您的函数。

int getId() const { return id;}; 

另外改变,

for (std::set<Test, compare>::const_iterator it = s.begin(); it != s.end(); ++it){ 
     std::cout << it->getId() << "\n";  // got error here 
    } 
相关问题