【问题标题】:Why isn't std::vector::at a const function?为什么 std::vector::at 不是 const 函数?
【发布时间】:2021-05-29 09:34:12
【问题描述】:

我正在尝试实现 std::vector 但遇到了问题。 根据 C++ 参考,std::vector::at 就像:

      reference at (size_type n);
const_reference at (size_type n) const;

我的问题是:我为什么不用reference at (size_type n) const;

感谢您的任何帮助或批评!


更新: 谢谢!我很清楚。

我的错是我不知道有和没有const 的函数也是一种过载。最初的设计是在 const 向量调用它时使用带有 const 的那个,所以它会返回一个 const_reference。当向量不是 const 时,返回值不应该是 const_reference。

但是如果我们将这两个函数都设为const,那么这两个函数除了返回类型之外没有区别,它不是合法的覆盖。所以前者不是设计为const,尽管它可以是const

谢谢!

【问题讨论】:

  • 你可以这样做,没问题。这违反了 C++ 标准,但可能会出乎其他人的意料。
  • v.at(42) = 1234
  • 成员函数后面的const 应用于隐式this 参数。所以成员函数 void Foo::Reset();void Foo::Dump() const; 有点像(伪代码)void Foo::Reset(Foo* const this)void Foo::Dump(Foo const* const this);
  • @Eljay 谢谢!这对我有很大帮助,因为我在编写该更新时认为它是 Foo const *this;但实际上正如您所指出的那样,它是 Foo const * const this

标签: c++ stdvector


【解决方案1】:

想想ref at (size_type n) const; 可能导致的问题。首先,您需要了解const_reference at (size_type n) const; 存在的原因。在const std::vector 中,一旦它被初始化,它或它的元素就不应该被改变(因为它毕竟是const)。普通的reference at (size_type n);适用于const 向量,因为它返回对元素的非const 引用,这意味着它可以更改。这违背了 consting 对象的想法,这就是为什么这种特定的重载不适用于 const 向量。

这就是const_reference at (size_type n) const; 出现的地方。你可能知道,结尾const 是对编译器和程序员的承诺,它不会改变它的对象或提供改变它的对象的机会,所以它可以与const 对象一起使用。在const_reference at (size_type n) const; 的情况下,确实如此:它返回一个const 引用,这意味着您获得的元素无法更改。这保证了你的const 向量确实是const 并且它不会被改变。

这就是为什么reference at (size_type n) const; 是个问题。你对编译器和程序员都撒谎,说在 const 对象上使用它是安全的,实际上它确实不是,因为它返回一个可变引用,你可以轻松更改你得到的元素at

问问自己:如果这个程序成功了,你不会感到震惊吗?

#include <vector>

int main()
{
    const std::vector<int> a = {1, 2, 3};
    a.at(0) = 10;
}

【讨论】:

  • reference at (size_type n) const 不是一个大“问题”,因为它不会编译
  • 谢谢!我很清楚这一点。我最初的想法是同时使用reference at (size_type n) const;creference at (size_type n) const;,但我没有意识到这不会形成合法的过载。再次感谢您的解释!
  • @463035818_is_not_a_number 可能取决于向量的实现方式。在this small test I did 中,编译器似乎无法捕捉到问题。
  • @mediocrevegetable1 哦,你是对的。我正在考虑返回对 const this 成员的非常量引用,这当然会失败。即使在 const foo 上,数组元素也不是 const 。
猜你喜欢
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-05
  • 2021-03-26
  • 1970-01-01
  • 2020-01-31
相关资源
最近更新 更多