C++ 为什么运算符[]是为const std::vector定义的,而不是为const std::map定义的?

C++ 为什么运算符[]是为const std::vector定义的,而不是为const std::map定义的?,c++,stdvector,language-design,stdmap,c++-standard-library,C++,Stdvector,Language Design,Stdmap,C++ Standard Library,有此代码: #include <map> #include <string> #include <vector> void foo1(const std::map<std::string, int> &m) { m["abcd"]; } void foo2(const std::vector<std::vector<int>> &v) { v[0]; } 仅为foo1

有此代码:

#include <map>
#include <string>
#include <vector>

void foo1(const std::map<std::string, int> &m)
{
    m["abcd"];
}

void foo2(const std::vector<std::vector<int>> &v)
{
    v[0];
}
仅为foo1提供错误,但不为foo2提供错误。据我所知,map->它有两个数组——一个用于键,另一个用于值。我知道常数映射给我常数int作为值。但向量也应该如此,因为通过[]访问元素也是常量向量,但是允许的。此外,通过[]访问值并不意味着我要立即写入数据。我可以读取该值,那么为什么连常量映射都没有运算符[]?当编译器不知道我是要写还是要读时

编辑
问题在于语言设计,而不是标准的引用。正如在comments->中一样,您需要1个操作符才能在映射操作符[]中写入。但需要两个运算符来表示向量写入运算符[],运算符=。为什么map::operator[]自动期望我要写?因此,通过提供的键创建新元素?我可以像在vector中一样尝试从该映射读取数据,如果该密钥对不存在,它可以给出错误或警告,但不需要立即创建它。

这是因为如果引用的元素不存在,std::map::operator[]会插入映射。因此,该方法不能声明为const,因此不能在const对象上调用。

这是因为如果引用的元素不存在,则std::map::operator[]会插入到映射中。因此,该方法不能声明为const,因此不能在const对象上调用。

此外,通过[]访问值并不意味着我要立即写入数据。在std::map的情况下:它会插入值,如果键不存在,它会插入值\u typekey,但在v[0]或std::vector的?运算符[]不插入元素的情况下,它应该创建新的向量。它只是访问它们。如果你越界访问它,你只会调用未定义的行为。你认为有意义或没有意义是无关紧要的。相关的是如何在C++标准中描述所需的行为,这是CPP首选中反映的。这就是它的定义。好吧,如果我理解的话,这是有道理的,你会问为什么[]对向量和映射的行为不一样。但是你的问题是编译器在这个场景中是怎么想的?编译器只是遵循语言规则。也许你可以重新表述这个问题,问一下为什么langauge的设计是这样的?而且,通过[]访问一个值并不意味着我想立即写一个数据。在std::map的情况下:它会插入值,如果键不存在,它会插入值\u typekey,但在v[0]或std::vector的?运算符[]不插入元素的情况下,它应该创建新的向量。它只是访问它们。如果你越界访问它,你只会调用未定义的行为。你认为有意义或没有意义是无关紧要的。相关的是如何在C++标准中描述所需的行为,这是CPP首选中反映的。这就是它的定义。好吧,如果我理解的话,这是有道理的,你会问为什么[]对向量和映射的行为不一样。但是你的问题是编译器在这个场景中是怎么想的?编译器只是遵循语言规则。也许你可以重新表述这个问题,问一下为什么langauge设计是这样的?如果是v[0],它不会创建新的对象向量?同样的规则在这里也适用,并且是允许的。如果是v[0],它不会创建新的对象向量吗?这是正确的。v[0]只返回v中的第0个元素,不进行插入或赋值。然而,有一个std::vector::operator[]的非常量重载,允许您编写v[0]=42;不,写入包括向量->运算符[],运算符=,中的两个操作,而不仅仅是映射->运算符[]中的一个操作就足以写入。从语言角度来看,这是没有意义的std::vector::operator[]和std::vector::operator=是根本不同的。第一个元素访问或写入单个元素,而第二个元素复制整个向量。对于v[0],它不会创建新的对象向量吗?同样的规则在这里也适用,并且是允许的。如果是v[0],它不会创建新的对象向量吗?这是正确的。v[0]只返回v中的第0个元素,不进行插入或赋值。然而,有一个std::vector::operator[]的非常量重载,允许您编写v[0]=42;不,写入包括向量->运算符[],运算符=,中的两个操作,而不仅仅是映射->运算符[]中的一个操作就足以写入。从语言角度来看,这是没有意义的std::vector::operator[]和std::vector::operator=是根本不同的。第一种方法访问或写入单个元素,而第二种方法复制整个向量。