C++ 错误:将xxx传递为';这';xxx丢弃限定符的参数 #包括 #包括 使用名称空间std; 班级学生{ 公众: int-id; 字符串名; 公众: StudentT(int-id,string-name):id(\u-id),name(\u-name){ } int getId(){ 返回id; } 字符串getName(){ 返回名称; } }; 内联布尔运算符“breaks const correction”@jfritz42:如果它丢弃volatile@Plasmah,则会造成混淆。错误消息将被拆分为“breaks const correctifier”和“打破了不稳定的正确性".现在,没有多少人会认为某些东西是不稳定的correct@Fred-您认为向不修改类实例的成员函数添加常量修饰符绝对是一项要求吗?在这种情况下,是否还有其他原因导致此错误?我对此表示怀疑,因为在我编写的大多数getter中,我没有向其添加常量修饰符。@Mahesh:是的,它是的一部分。我不确定常量从哪里来,但我怀疑集合正在从迭代器返回常量引用,以防止实例更改,从而使集合无效。@Mahesh:不会通过我的代码审查。我有一个同事称我为“常量”.8v)将foo obj;更改为const foo obj;一次,看看会发生什么。或者将const引用传递给foo@Mahesh:就像我说的那样,如果集合中的元素发生更改,顺序可能会被打乱,然后集合就不再有效。在映射中,只有cons键t。在集合中,整个对象实际上是关键。@Mahesh:const是必需的,否则不能用const对象调用它们。请参阅函数f()在我的回答中。解释得很清楚。谢谢。但是我想知道你的最后一段代码。为什么在函数参数中使用引用?const StudentT&s1,const StudentT&s2?@RafaelAdel:你使用引用来避免不必要的复制,并且const因为函数不需要修改对象,所以常数enfo inline bool operator< (const StudentT & s1, const StudentT & s2) { return s1.getId() < s2.getId(); } typedef typename _Rep_type::const_iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; 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.) struct Count{ uint32_t c; Count(uint32_t i=0):c(i){} uint32_t getCount(){ return c; } uint32_t add(const Count& count){ uint32_t total = c + count.getCount(); return total; } }; error: passing 'const xy_stl::Count' as 'this' argument discards qualifiers [-fpermissive]

C++ 错误:将xxx传递为';这';xxx丢弃限定符的参数 #包括 #包括 使用名称空间std; 班级学生{ 公众: int-id; 字符串名; 公众: StudentT(int-id,string-name):id(\u-id),name(\u-name){ } int getId(){ 返回id; } 字符串getName(){ 返回名称; } }; 内联布尔运算符“breaks const correction”@jfritz42:如果它丢弃volatile@Plasmah,则会造成混淆。错误消息将被拆分为“breaks const correctifier”和“打破了不稳定的正确性".现在,没有多少人会认为某些东西是不稳定的correct@Fred-您认为向不修改类实例的成员函数添加常量修饰符绝对是一项要求吗?在这种情况下,是否还有其他原因导致此错误?我对此表示怀疑,因为在我编写的大多数getter中,我没有向其添加常量修饰符。@Mahesh:是的,它是的一部分。我不确定常量从哪里来,但我怀疑集合正在从迭代器返回常量引用,以防止实例更改,从而使集合无效。@Mahesh:不会通过我的代码审查。我有一个同事称我为“常量”.8v)将foo obj;更改为const foo obj;一次,看看会发生什么。或者将const引用传递给foo@Mahesh:就像我说的那样,如果集合中的元素发生更改,顺序可能会被打乱,然后集合就不再有效。在映射中,只有cons键t。在集合中,整个对象实际上是关键。@Mahesh:const是必需的,否则不能用const对象调用它们。请参阅函数f()在我的回答中。解释得很清楚。谢谢。但是我想知道你的最后一段代码。为什么在函数参数中使用引用?const StudentT&s1,const StudentT&s2?@RafaelAdel:你使用引用来避免不必要的复制,并且const因为函数不需要修改对象,所以常数enfo inline bool operator< (const StudentT & s1, const StudentT & s2) { return s1.getId() < s2.getId(); } typedef typename _Rep_type::const_iterator iterator; typedef typename _Rep_type::const_iterator const_iterator; 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.) struct Count{ uint32_t c; Count(uint32_t i=0):c(i){} uint32_t getCount(){ return c; } uint32_t add(const Count& count){ uint32_t total = c + count.getCount(); return total; } }; error: passing 'const xy_stl::Count' as 'this' argument discards qualifiers [-fpermissive],c++,C++,每当您看到“discards qualifier”时,它都在谈论const或volatilestd::set中的对象存储为const StudentT。因此当您尝试调用getId()时对于const对象,编译器检测到问题,主要是在const对象上调用非const成员函数,这是不允许的,因为非const成员函数不承诺不修改对象;因此编译器将安全地假设getId()可能会尝试修改该对象,但同时也会注意到该对象是常量;因此,任何修改常量对象的尝试都应该是错误的。因此编译器会生成错误消息 解决方案很简单

每当您看到“discards qualifier”时,它都在谈论
const
volatile
std::set中的对象存储为
const StudentT
。因此当您尝试调用
getId()时
对于
const
对象,编译器检测到问题,主要是在const对象上调用非const成员函数,这是不允许的,因为非const成员函数不承诺不修改对象;因此编译器将安全地假设
getId()
可能会尝试修改该对象,但同时也会注意到该对象是常量;因此,任何修改常量对象的尝试都应该是错误的。因此编译器会生成错误消息

解决方案很简单:使函数常量为:

int getId() const {
    return id;
}
string getName() const {
    return name;
}
这是必要的,因为现在您可以在const对象上调用
getId()
getName()
,如下所示:

int getId() const {
    return id;
}
string getName() const {
    return name;
}
void f(const StudentT&s)
{
实际上,C++标准(即)指出(TNX到XEO和@ Ben Voigt指出我):< /P>
23.2.4关联容器
5用于设置和多重设置值类型 与键类型相同。对于映射 和multimap它等于在一个关联的 容器是不可变的。
6的迭代器 关联容器是 双向迭代器类别 关联容器,其中 类型与键类型相同,两者都是 迭代器和常量迭代器是 常量迭代器。未指定 是否使用迭代器和 常量迭代器是相同的类型

所以VC++2008纯粹软件的实现是错误的


旧答案:

之所以出现此错误,是因为在std库的某些实现中,
set::iterator
set::const\u iterator
相同

例如,libstdc++(与g++一起提供)有它(请参阅以获取完整的源代码):

在SGI的声明中指出:

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

另一方面,VC++2008 Express编译您的代码时,不会抱怨您正在
set::iterator
s上调用非常量方法。

让我给出一个更详细的示例。关于以下结构:

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.)

如上所述,IDE(CLion)将给出提示
对const对象调用非const函数“getCount”。在方法
add
count
中声明为const对象,但方法
getCount
不是const方法,因此
count.getCount()
可以更改
计数中的成员

编译错误如下(我的编译器中的核心消息):

要解决上述问题,您可以:

  • 将方法
    uint32\u t getCount(){…}
    更改为
    uint32\u t getCount()const{…}
    。因此
    count.getCount()
    不会更改
    count
    中的成员
  • uint32\u t add(const Count&Count){…}
    更改为
    uint32\u t add(Count&Count){…}
    。因此
    Count
    不关心更改其中的成员
  • 至于您的问题,std::set中的对象存储为const StudentT,但是方法
    getId
    getName
    不是const,所以您给出了上述错误


    您还可以查看此问题以了解更多详细信息。

    代码段中的第35行在哪里?我希望GCC能够改进此错误消息,例如“discards qualifiers”->“breaks const correction”@jfritz42:如果它丢弃
    volatile
    @Plasmah,则会造成混淆。错误消息将被拆分为“breaks const correctifier”和“打破了不稳定的正确性".现在,没有多少人会认为某些东西是不稳定的correct@Fred-您认为向不修改类实例的成员函数添加常量修饰符绝对是一项要求吗?在这种情况下,是否还有其他原因导致此错误?我对此表示怀疑,因为在我编写的大多数getter中,我没有向其添加常量修饰符。@Mahesh:是的,它是的一部分。我不确定
    常量
    从哪里来,但我怀疑
    集合
    正在从迭代器返回常量引用,以防止实例更改,从而使集合无效。@Mahesh:不会通过我的代码审查。我有一个同事称我为“常量”.8v)将
    foo obj;
    更改为
    const foo obj;
    一次,看看会发生什么。或者将
    const
    引用传递给
    foo
    @Mahesh:就像我说的那样,如果
    集合中的元素发生更改,顺序可能会被打乱,然后集合就不再有效。在
    映射中,只有
    cons键t
    。在
    集合中,整个对象实际上是关键。@Mahesh:const是必需的,否则不能用const对象调用它们。请参阅函数
    f()
    在我的回答中。解释得很清楚。谢谢。但是我想知道你的最后一段代码。为什么在函数参数中使用引用?
    const StudentT&s1,const StudentT&s2
    ?@RafaelAdel:你使用引用来避免不必要的复制,并且
    const
    因为函数不需要修改对象,所以
    常数
    enfo
    inline bool operator< (const StudentT & s1, const StudentT & s2)
    {
        return  s1.getId() < s2.getId();
    }
    
    typedef typename _Rep_type::const_iterator            iterator;
    typedef typename _Rep_type::const_iterator            const_iterator;
    
    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.)
    
    struct Count{
        uint32_t c;
    
        Count(uint32_t i=0):c(i){}
    
        uint32_t getCount(){
            return c;
        }
    
        uint32_t add(const Count& count){
            uint32_t total = c + count.getCount();
            return total;
        }
    };
    
    error: passing 'const xy_stl::Count' as 'this' argument discards qualifiers [-fpermissive]