【问题标题】:Why is operator[] defined for const std::vector, but not for const std::map?为什么为 const std::vector 定义了 operator[],而不为 const std::map 定义了 operator[]?
【发布时间】:2020-07-29 22:36:53
【问题描述】:

拥有此代码:

#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 -> 它有 2 个数组 - 一个用于键,第二个用于值。我知道const map 给了我const int 作为价值。但是vector&lt;vector&lt;int&gt;&gt; 也应该如此,因为通过[] 访问元素也是const vector&lt;int&gt;,但是是允许的。此外,通过[] 访问一个值并不立即意味着我想write 一个数据。我只能读取该值,那么为什么即使const map 也没有operator[]? (当编译器不知道我想写还是读时)。

编辑

问题是语言设计,而不是标准引用。与 cmets 一样 -> 您需要 1 个运算符来写入映射 operator[]。但是向量写入需要 2 个运算符operator[]operator=。为什么map::operator[] 会自动期望我想写? (因此通过提供的键创建新元素)?我可以像在向量中一样只是尝试从该映射中读取,如果该键(对)不存在,它可能会给出错误或警告,但无需立即创建它。

【问题讨论】:

  • "此外,通过[] 访问一个值并不立即意味着我想write 一个数据。" 在std::map 的情况下:确实如此,如std::map::operator[] 的文档指出:“如果密钥不存在,则插入 value_type(key, T())
  • 但是在v[0]的情况下应该创建新的vector&lt;int&gt;还是?
  • operator[] of std::vector 不插入元素。它只是访问它们。如果您越界访问它,您只会调用未定义的行为。
  • 你相信什么是有道理的,或者不是无关紧要。相关的是 C++ 标准中如何描述所需的行为(这反映在 cppreference 中)。这就是它的定义方式。
  • 好吧,这是有道理的(如果我理解,您会问为什么[]vectormap 的行为方式不同)。但是你的问题是“编译器在这个场景中是怎么想的”编译器只是遵循语言规则。也许您可以改写问题,问为什么语言设计是这样的?

标签: c++ stdvector language-design stdmap c++-standard-library


【解决方案1】:

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

【讨论】:

  • 如果是v[0],它不会创建新对象vector&lt;int&gt;?相同的规则在这里适用并且是允许的
  • 并且在 v[0] 的情况下它不会创建新的对象向量? 这是正确的。 v[0] 只返回v 中的第零个元素,不进行插入或分配。但是,std::vector::operator[] 有一个非常量重载,可以让您编写类似 v[0] = 42; 的内容
  • 不,到write 包括vector 中的2 个操作-> operator[]operator=,而不仅仅是map 中的一个-> operator[] 足以write .从语言的角度来看,这是没有意义的
  • std::vector::operator[]std::vector::operator= 根本不同。第一个访问(或写入)单个元素,而第二个复制整个向量。
猜你喜欢
  • 1970-01-01
  • 2020-01-31
  • 2016-10-03
  • 2014-08-30
  • 2018-07-30
  • 2015-12-16
  • 2023-03-21
  • 2012-10-20
  • 1970-01-01
相关资源
最近更新 更多