gpt4 book ai didi

c++ - 为什么我可以更新 const 成员函数中的成员变量?

转载 作者:行者123 更新时间:2023-12-02 09:49:31 25 4
gpt4 key购买 nike

我正在尝试实现一个类似于在 STL 中实现的链接列表。在实现迭代器时,我创建了一些 const 成员函数(因此用户可以使用 const 迭代器)并注意到我能够更新成员变量而不会出现编译器错误。该代码使用模板,但我测试它调用了一个使用 begin() 和一个 const 列表的函数,所以我知道修改成员变量的模板函数是由编译器生成的。有谁知道为什么会这样?有问题的函数是 operator++ 的 const 版本。

这是我的程序的一个版本,去掉了不相关的细节。

template<typename E>
struct Link {
E val {};
Link* next = nullptr;
Link* prev = nullptr;
};

template<typename E>
struct List {
struct Iterator {
Iterator(Link<E>* c) : curr{c} { }

Iterator& operator++();
const Iterator& operator++() const;

const E& operator*() const {return curr->val;}
E& operator*() {return curr->val;}

// ...
private:
Link<E>* curr;
};

// Constructors, etc ...
// Operations ...

E& front() {return head->val;}
const E& front() const {return head->val;}

Iterator begin() {return Iterator{head};}
const Iterator begin() const {return Iterator{head};}
// Other iterator stuff ...

private:
Link<E>* head;
Link<E>* tail;
int sz;
};

/*---------------------------------------------*/

template<typename E>
typename List<E>::Iterator& List<E>::Iterator::operator++() {
curr = curr->next;
return *this;
}

template<typename E>
const typename List<E>::Iterator&
List<E>::Iterator::operator++() const
{
curr = curr->next;
return *this;
}


我认为从概念上讲,即使它修改了成员变量,制作 const 版本的 operator++ 也是有意义的。 const 迭代器实际上是指 Link 指针的内容为 const,这正是它在取消引用运算符中返回 const E& 的原因。因此,使用 const 迭代器,您永远无法更新迭代器的内容。

如果我应该在代码片段中包含任何内容,请告诉我,谢谢!

最佳答案

模板函数在实例化之前实际上不会检查错误。如果你不给他们打电话,他们只是坐在那里不被注意,炸弹等着引爆。添加对 Iterator::operator++() const 的调用后,您将收到编译器错误。 .

例如,我添加了:

int main() {
List<int> list;
const List<int>::Iterator iter = list.begin();
++iter;
}

现在clang提示:
main.cpp:52:10: error: cannot assign to non-static data member within const
member function 'operator++'
curr = curr->next;
~~~~ ^
main.cpp:61:3: note: in instantiation of member function
'List<int>::Iterator::operator++' requested here
++iter;
^
main.cpp:14:25: note: member function 'List<int>::Iterator::operator++' is
declared const here
const Iterator& operator++() const;
^

( Repl)

I think conceptually, it makes sense to make a const version of operator++ even though it modifies member variables. A const iterator actually refers to the contents of the Link pointer being const, which is exactly why it returns a const E& in the dereference operator. Thus, with a const iterator, you can never update the contents of the iterator.



一个 const迭代器不应该是可变的,也不能有 ++运算符(operator)。 STL 实际上有单独的 iteratorconst_iterator类型。一个 const_iterator体现了您所描述的概念:迭代器本身是可变的,但它指向的是 const .

我建议您效仿并创建一个单独的 ConstIterator类(class)。

关于c++ - 为什么我可以更新 const 成员函数中的成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61378940/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com