【问题标题】:error: assignment of member in read-only object错误:在只读对象中分配成员
【发布时间】:2022-04-02 01:58:21
【问题描述】:

IDEONE:http://ideone.com/uSqSq7

#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;

struct node
{
    int value, position;
    bool left, right;
    bool operator < (const node& a) const
    {
        return value < a.value;
    }
};

int main()
{
    int n;
    cin >> n;

    vector < node > a(n);
    set < node > s;

    for (auto &i: a)
    {
        cin >> i.value;
        i.left=i.right=0;
    }

    a[0].position=1;
    s.insert(a[0]);

    for (int i=1; i<n; i++)
    {
        auto it=s.upper_bound(a[i]);
        auto it2=it; --it2;
        if (it==s.begin())
        {
            a[i].position=2*it->position;
            s.insert(a[i]);
            it->left=1;
        }
        else if (it==s.end())
        {
            a[i].position=2*(--it)->position+1;
            s.insert(a[i]);
            it->right=1;
        }
        else
        {
            if (it2->right==0)
            {
                a[i].position=2*it2->position+1;
                s.insert(a[i]);
                it2->right=1;
            }
            else
            {
                a[i].position=2*it->position;
                s.insert(a[i]);
                it->left=1;
            }
        }
    }

    for (auto i: a) cout << i.position << ' ';
}

当我编译这段代码时,我得到了

error: assignment of member ‘node::right’ in read-only object

我认为这与bool operator &lt; 中的const 有关,但我无法摆脱它,因为它是创建集合所必需的。

【问题讨论】:

  • 产生此错误的代码行是什么?
  • 我尝试更改使用upper_bound返回迭代器的对象的值的所有行。我添加了一个ideone链接。 (ideone.com/­uSqSq7)
  • 你可以尝试用set&lt;node&gt;::iterator it=...替换auto it = ...
  • 确实,set&lt;node&gt;::iterator 类型解析为 const 迭代器...

标签: c++


【解决方案1】:

Angelika Langer 曾经为此写过一篇文章:Are Set Iterators Mutable or Immutable?。

您可以通过将set 排序的Node 成员不重要定义为mutable 来解决此问题:

mutable bool left, right;

(见building version in ideone。)

就个人而言,我会考虑使用map 将不可变部分映射到可变部分的设计。

【讨论】:

    【解决方案2】:

    问题:

    请记住,std::set 中的键是常量。将密钥插入集合后,您将无法更改密钥。因此,当您取消引用迭代器时,它必然会返回一个常量引用。

    const node& n = (*it);
    n->left = 1; //It will not allow you to change as n is const &.
    

    解决方案:

    正如 Ami Tavory 回答的那样,您可以将 left 和 right 声明为可变的。

    【讨论】:

      猜你喜欢
      • 2012-08-28
      • 2019-09-24
      • 1970-01-01
      • 1970-01-01
      • 2016-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多