c++ const“this”指针是否暗示其所有成员都是常量?

gkn4icbw  于 2023-01-03  发布在  其他
关注(0)|答案(1)|浏览(102)

我知道,如果我们在函数声明后添加"const"限定符,则意味着隐式"this"指针变为const,因此我们无法直接修改任何成员
但是,在const成员函数中,每个成员是否也自动变为const?
为了说明我想问的问题,这里有一个演示程序

#include <vector>

struct Foo {
    int a;
    int b;
};

class Demo {

public:
    Demo() = default;

    void bar(std::vector<Foo>::iterator it) const {}

    void baz() const {
        // begin() is supposed to return iterator, not const_iterator
        bar(vector.begin());
    }

private:
    std::vector<Foo> vector;
};

int main(void)
{
    Demo d;
    d.baz();

    return 0;
}

在baz()方法中,我调用std::vector::begin()方法,根据doc,它可以返回iteratorconst_iterator

iterator begin() noexcept;
const_iterator begin() const noexcept;

我的理解是,如果成员"vector"声明为const,例如

private:
  const std::vector<Foo> vector;

然后调用返回const_iterator的重载表单,否则调用返回可变iterator的重载表单,这是当前的情况
当我试图编译它时

g++ --std=c++17 -Wall

我遇到了编译错误

main.cpp:17:13: error: no viable conversion from '__wrap_iter<std::__1::vector<Foo, std::__1::allocator<Foo> >::const_pointer>' to
      '__wrap_iter<std::__1::vector<Foo, std::__1::allocator<Foo> >::pointer>'
        bar(vector.begin());
            ^~~~~~~~~~~~~~

其实质上返回const_iterator而不是iterator
现在我很困惑,我没有声明vector为常量,为什么返回const_iterator的重载表单仍然被调用?
是因为baz()声明为const吗?我知道在const成员函数中,所有与当前对象直接关联的内存都不应该被修改,但我不希望这会对函数重载造成这样的影响。我希望vector.begin()在且仅在vector声明为const成员时返回const_iterator,例如:

private:
  const std::vector<Foo> vector;

先谢了

e4yzc0pl

e4yzc0pl1#

正如大家所说,如果thisconst,那么无论this指向什么,其成员都是const
要添加,您可以在const函数或上下文中将成员变量设置为非const,如果您使用mutable关键字声明它......如果您想要这种行为。

class Demo {
public:
  Demo() = default;

  void bar(std::vector<Foo>::iterator it) const {}

  void baz() const
  {
    // begin() now returns iterator instead of const_iterator
    bar(vector.begin());
  }

private:
  mutable std::vector<Foo> vector; // vector is non-const in const functions
};

相关问题