我知道如果我们在函数声明后添加一个"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,它可以返回iterator
或const_iterator
iterator begin() noexcept;
const_iterator begin() const noexcept;
我的理解是,如果成员"向量"被声明为常量,例如
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());
^~~~~~~~~~~~~~
本质上vector.begin()
返回const_iterator
而不是iterator
。
现在我很困惑,我没有将vector
声明为 const,为什么仍然调用返回const_iterator
的重载形式?
是因为 baz() 被声明为 const 吗?我知道在 const 成员函数中,不应修改与当前对象直接关联的所有内存,但我不希望这会对函数重载造成如此大的影响。我希望vector.begin()
返回一个const_iterator当且仅当向量被声明为常量成员时,
private:
const std::vector<Foo> vector;
提前致谢
就像每个人都说的那样,如果this
是const
那么this
指向的任何成员都是const
。
要添加,您可以使用mutable
关键字声明成员变量,则可以在const
函数或上下文中使成员变量非const
...如果你想要那种行为。
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
};