C++ 对非常量对象的常量引用
我很难理解为什么我不能对一个可变对象有一个不变的引用?如果我像这样传递对容器的引用:C++ 对非常量对象的常量引用,c++,reference,C++,Reference,我很难理解为什么我不能对一个可变对象有一个不变的引用?如果我像这样传递对容器的引用: auto f(const map<int, int>& x) -> decltype(non-const map iterator) {...} autof(常量映射&x)->decltype(非常量映射迭代器){…} 它认为x是常量,我请求它的任何迭代器都是const\u迭代器类型 我想要以下(或者我想是这样): autof(映射和常量x)->decltype(非常量映射迭代器)
auto f(const map<int, int>& x) -> decltype(non-const map iterator) {...}
autof(常量映射&x)->decltype(非常量映射迭代器){…}
它认为x
是常量,我请求它的任何迭代器都是const\u迭代器
类型
我想要以下(或者我想是这样):autof(映射和常量x)->decltype(非常量映射迭代器)
但它不编译
这并不难解决,但我希望我的项目的代码库中有一些关于常量的一致性。长话短说,您不能以任何可靠的方式从
常量
std容器中获得迭代器
为了说明为什么会这样,请看一下容器是如何实现的
template<typename T>
class map
{
struct node {
T data;
node *lchild, *rchild, *parent;
};
public:
iterator begin();
const_iterator begin() const;
private:
node* head;
};
如果容器天真地返回一个迭代器
,即使它是用常量
限定的,编译器也不会抱怨,毕竟容器中没有任何语法变化
// this is legal but wrong in a const map
head->data = T{};
// constness only prevents this
head = nullptr;
但是,由于容器在概念上是指针和指针指向的内容,因此当使用const
限定时返回迭代器在语义上是错误的。为了解决这个问题,我们引入了const
重载,保证const
容器将真正成为const
就map
而言,发出一个迭代器
会立即破坏const
应该承担的契约。映射
在发出一个迭代器后,无法确保其常量,您可以或不可以使用它对内容进行变异。没有“常量引用”这样的东西。引用没有可变结构。该引用已经是不可变的,不能使其引用其他变量。您有一个对const
对象的引用,这就是为什么您得到const\u迭代器的原因。为什么你不能像在第二个代码示例中建议的那样通过引用来获得你想要的行为呢?你的问题的标题是错误的(要求与你所说的相反)。您正试图从const
容器中获取非const
引用。为什么需要一个迭代器来更改const
容器的元素?我主要是希望在调用函数时弄清楚语法。希望调用f(map\u 01)
并向用户(我)保证map\u 01
不会更改。如果没有const
限定符,我仍然可以通过引用传递,但是我得到了什么保证(除了我是作者之外)函数f
不会修改map\u 01
?您的第一个示例允许编译器对map参数强制执行不变性。
// this is legal but wrong in a const map
head->data = T{};
// constness only prevents this
head = nullptr;