错误:将 const 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:错误:将“const StudentT”作为“int StudentT::getId()”的“this”参数传递会丢弃限定符
../main.cpp:35:错误:将“const StudentT”作为“std::string StudentT::getName()”的“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;
}
In line:
cout << itr->getId() << " " << itr->getName() << endl;
It give an error that:
../main.cpp:35: error: passing 'const StudentT' as 'this' argument of 'int StudentT::getId()' discards qualifiers
../main.cpp:35: error: passing 'const StudentT' as 'this' argument of 'std::string StudentT::getName()' discards qualifiers
What's wrong with this code?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
std::set
中的对象存储为const StudentT
。因此,当您尝试使用 const 对象调用 getId() 时,编译器会检测到问题,主要是您在 const 对象上调用非 const 成员函数,而该函数不是 const 对象。允许,因为非常量成员函数不承诺不修改对象;因此编译器将做出一个安全假设,即getId()
可能会尝试修改该对象,但同时,它也会注意到该对象是const;所以任何修改 const 对象的尝试都应该是一个错误。因此编译器会生成错误消息。解决方案很简单:将函数设置为 const:
因为现在您可以对 const 对象调用
getId()
和getName()
:这是必要的, 应该将
operator<
实现为:注意参数现在是
const
引用。The objects in the
std::set
are stored asconst StudentT
. So when you try to callgetId()
with theconst
object the compiler detects a problem, mainly you're calling a non-const member function on const object which is not allowed because non-const member functions make NO PROMISE not to modify the object; so the compiler is going to make a safe assumption thatgetId()
might attempt to modify the object but at the same time, it also notices that the object is const; so any attempt to modify the const object should be an error. Hence compiler generates an error message.The solution is simple: make the functions const as:
This is necessary because now you can call
getId()
andgetName()
on const objects as:As a sidenote, you should implement
operator<
as :Note parameters are now
const
reference.不修改类实例的成员函数应声明为
const
:任何时候您看到“discards qualifiers”,它都在谈论
const
或volatile
。Member functions that do not modify the class instance should be declared as
const
:Anytime you see "discards qualifiers", it's talking about
const
orvolatile
.实际上是 C++ 标准(即 C++ 0x 草案) 说(感谢 @Xeo 和 @Ben Voigt 向我指出了这一点):
所以 VC++ 2008 Dinkumware 实现是错误的。
旧答案:
您收到该错误是因为在 std lib 的某些实现中,
set::iterator
与set::const_iterator
相同。例如 libstdc++ (随 g++ 一起提供)有它(请参阅此处 整个源代码):
在 SGI 的 docs 它指出:
另一方面,VC++ 2008 Express 编译您的代码时不会抱怨您在
set::iterator
上调用非常量方法。Actually the C++ standard (i.e. C++ 0x draft) says (tnx to @Xeo & @Ben Voigt for pointing that out to me):
So VC++ 2008 Dinkumware implementation is faulty.
Old answer:
You got that error because in certain implementations of the std lib the
set::iterator
is the same asset::const_iterator
.For example libstdc++ (shipped with g++) has it (see here for the entire source code):
And in SGI's docs it states:
On the other hand VC++ 2008 Express compiles your code without complaining that you're calling non const methods on
set::iterator
s.让我举一个更详细的例子。对于以下结构:
如您所见,IDE(CLion)将给出提示
在 const 对象上调用非 const 函数“getCount”
。在方法add
中,count
被声明为 const 对象,但方法getCount
不是 const 方法,因此count.getCount()
可能会更改count
中的成员。编译错误如下(我的编译器中的核心消息):
要解决上述问题,您可以:
uint32_t getCount(){...}
更改为uint32_t getCount() const { ...}
。因此count.getCount()
不会更改count
中的成员。或
uint32_t add(const Count& count){...}
更改为uint32_t add(Count& count){...}
。所以count
不关心其中成员的更改。至于您的问题, std::set 中的对象存储为 const StudentT,但方法
getId
和getName
不是 const,因此您给出了上述错误。您还可以看到这个问题 'const 的含义' 最后在类的函数声明中? 了解更多详细信息。
Let's me give a more detail example. As to the below struct:
As you see the above, the IDE(CLion), will give tips
Non-const function 'getCount' is called on the const object
. In the methodadd
count
is declared as const object, but the methodgetCount
is not const method, socount.getCount()
may change the members incount
.Compile error as below(core message in my compiler):
To solve the above problem, you can:
uint32_t getCount(){...}
touint32_t getCount() const {...}
. Socount.getCount()
won't change the members incount
.or
uint32_t add(const Count& count){...}
touint32_t add(Count& count){...}
. Socount
don't care about changing members in it.As to your problem, objects in the std::set are stored as const StudentT, but the method
getId
andgetName
are not const, so you give the above error.You can also see this question Meaning of 'const' last in a function declaration of a class? for more detail.