我有以下代码
#include <string>
int Foo(const std::string& str){
std::string::iterator start;
start = str.begin();
return 0;
}
当我使用GCC 4.7.3编译它时,我收到一个错误。我怀疑错误弹出,因为我正在尝试分配
std::string::const_iterator;
到
std::string::iterator
所以更改行
std::string::iterator start;
要
std::string::const_iterator start;
精确编译。
我的问题是std :: string成员函数begin()如何识别它所调用的对象是const,因此返回一个const_iterator。
使问题更加普遍:
我是否可以更改或以某种方式重载类成员函数,以便在被const对象调用时采取不同的行为?
答案 0 :(得分:3)
我的问题是std :: string成员函数begin()如何识别它所调用的对象是const,因此返回一个const_iterator。
begin
有两个重载:
iterator begin();
const_iterator begin() const;
选择哪一个取决于调用成员函数时隐式this
参数的类型 - 在您的情况下,它是std::string&
或const std::string&
。
n3337,13.3.1
2候选函数集可以包含要解析的成员函数和非成员函数 相同的参数列表。因此,参数和参数列表在此异构中是可比较的 set,成员函数被认为有一个额外的参数,称为隐式对象参数,其中 表示已调用成员函数的对象。出于重载解析的目的, 静态和非静态成员函数都有一个隐式对象参数,但构造函数没有。
只能在const
限定对象参数上调用const
限定成员函数。
编译器如何知道str
是const?好吧,你在Foo
的声明中告诉了它。
答案 1 :(得分:0)
我的问题是std :: string成员函数begin()如何识别 它被调用的对象是const,因此返回一个 常量性。
符合const
条件的begin()
method has an overload返回const_iterator
。被const
限定意味着它是从被调用的对象const
iterator begin();
const_iterator begin() const; // This one
当str
为const
时,第二个被调用,因此返回的对象为const_iterator
,您尝试分配给iterator
这是无效的因此错误。
我可以更改或以某种方式重载类成员函数来执行操作 被const对象调用时有何不同?
使用auto
!而不是做
std::string::iterator start;
start = str.begin();
待办事项
auto start = str.begin();
有了这个,你实际上正在使用begin()
返回的确切类型。
但是,您可能以错误的方式执行操作,因为您是否需要const或非const迭代器取决于您要实现的任务。作为一般准则,除非您打算修改容器内的元素,否则始终使用const迭代器。
答案 2 :(得分:0)
如果对象是const,编译器会自动选择const成员函数。
您必须提供两个成员函数:
void someMethod();
void someMethod() const;