c++ - 错误:将XXX作为xxx的“this”参数丢弃限定符


#include <iostream>
#include <set>

using namespace std;

class StudentT {

public:
    int id;
    string name;
public:
    StudentT(int _id, string _name) : id(_id), name(_name) {
    }
    int getId() {
        return id;
    }
    string getName() {
        return name;
    }
};

inline bool operator< (StudentT s1, StudentT s2) {
    return  s1.getId() < s2.getId();
}

int main() {

    set<StudentT> st;
    StudentT s1(0, "Tom");
    StudentT s2(1, "Tim");
    st.insert(s1);
    st.insert(s2);
    set<StudentT> :: iterator itr;
    for (itr = st.begin(); itr != st.end(); itr++) {
        cout << itr->getId() << " " << itr->getName() << endl;
    }
    return 0;
}

一致:

cout << itr->getId() << " " << itr->getName() << endl;

它给出了一个错误:

../main.cpp:35:错误:作为'int'StudentT :: getId()的'this'参数传递'const StudentT'丢弃限定符

../main.cpp:35:错误:将'const StudentT'作为'std :: string'的参数传递给StudentT :: getName()'抛弃限定符

这个代码有什么问题? 谢谢!



Answers



std::set中的对象存储为const StudentT 。 所以当你试图用const对象调用getId() ,编译器检测到一个问题,即你在const对象上调用一个非const成员函数,这是不允许的,因为非const成员函数使得NO PROMISE不能修改目的; 所以编译器会做一个安全的假设, getId()可能试图修改对象,但同时也注意到对象是const的; 所以任何修改const对象的尝试都应该是错误的。 因此编译器生成错误信息。

解决方法很简单:使函数的const为:

int getId() const {
    return id;
}
string getName() const {
    return name;
}

这是必要的,因为现在你可以在const对象上调用getId()getName()

void f(const StudentT & s)
{
     cout << s.getId();   //now okay, but error with your versions
     cout << s.getName(); //now okay, but error with your versions
}

作为旁注,你应该实现operator< as:

inline bool operator< (const StudentT & s1, const StudentT & s2)
{
    return  s1.getId() < s2.getId();
}

注意参数现在是const引用。




不修改类实例的成员函数应声明为const

int getId() const {
    return id;
}
string getName() const {
    return name;
}

任何时候你看到“丢弃限定符”,它是在谈论constvolatile




其实C ++标准(即C ++ 0x草案 )说(tnx to @Xeo&@Ben Voigt指出了我):

23.2.4关联容器
5对于set和multiset,其值类型与键类型相同。 对于map和multimap,它等于pair。 关联容器中的键是不可变的。
6关联容器的迭代器是双向迭代器类别。 对于值类型与键类型相同的关联容器,iterator和const_iterator都是常量迭代器。 iterator和const_iterator是否是相同的类型是未指定的。

所以VC ++ 2008 Dinkumware实现有问题。

老答案:

你有这个错误,因为在std库的某些实现中, set::iteratorset::const_iterator是一样的。

例如libstdc ++(附带g ++)有它(参见这里的整个源代码):

typedef typename _Rep_type::const_iterator            iterator;
typedef typename _Rep_type::const_iterator            const_iterator;

在SGI的文件中,它指出:

iterator       Container  Iterator used to iterate through a set.
const_iterator Container  Const iterator used to iterate through a set. (Iterator and const_iterator are the same type.)

另一方面,VC ++ 2008 Express编译你的代码而不抱怨你在set::iterator上调用非const方法。










Tags