VS2013中的错误c3892迭代器问题

时间:2014-02-17 05:52:04

标签: c++ visual-c++ visual-studio-2012 stl

我正在将Visual Studio 2008 VC ++项目迁移到Visual Studio 2013.我在迁移其中一个项目时收到错误C3892。以下是一些重现问题的示例代码:

int _tmain(int argc, _TCHAR* argv[])
{
    struct student
    {
        int id;
        int marks;
        bool changed;

        bool operator < (const student& refParam) const
        {
            return false ;
        }
        student(int a,int b)
        {
            id=a;
            marks=b;
            changed=true;
        }
    };

    student x(10,500),y(15,600);
    std::multiset<student> myset;
    myset.insert(x);
    myset.insert(y);
    std::multiset<student>::reverse_iterator iter;
    for (iter=myset.rbegin(); iter != myset.rend(); ++iter)
    {
        std::cout<<iter->id<<"\n";
        std::cout<<iter->marks<<"\n";
        std::cout<<iter->changed<<"\n";
        iter->changed=false;
    }

    return 0;
}

尝试编译以上内容会引发错误:

error C3892: 'std::_Revranit<_RanIt,_Base>::operator ->' : you cannot assign to a variable that is const

但是,相同的代码在Visual Studio 2008中编译时没有错误。我应该更改项目中的值吗?

2 个答案:

答案 0 :(得分:1)

C ++ 11中的所有multiset迭代器都指向const元素。如果要修改元素,则需要将其删除并插入新元素。 作为hack,您可以将struct变量声明为可变(不推荐)。只有在你确定自己在做什么时才这样做

mutable bool changed;

另外你应该写一个合适的运算符&lt;。

答案 1 :(得分:-2)

根据在VS2010之后实现的C ++ 11标准,我们无法更改集合或多集中的元素。默认情况下,迭代器引用一个常量元素。如果我们想要更改集合或多集中的元素,我们必须进行显式类型转换。

在上面的代码中iter->changed=false会抛出C3892错误,但如果我们将语句更改为

const_cast<student&>(*item).changed=false;

相反,它会编译而没有任何错误。