0

我有以下一段代码

#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 对象调用时采取不同的行为吗?

4

3 回答 3

3

我的问题是 std::string 成员函数 begin() 如何识别它被调用的对象是 const 并因此返回一个 const_iterator。

有两个重载begin

iterator       begin();
const_iterator begin() const;

选择哪一个取决于this调用成员函数时隐式参数的类型 - 在您的情况下,它是std::string&or const std::string&

n3337, 13.3.1

2 候选函数集可以包含要针对同一个参数列表解析的成员函数和非成员函数。为了使实参和形参列表在这个异构集合中具有可比性,成员函数被认为有一个额外的形参,称为隐式对象形参,它表示已为其调用成员函数的对象。出于重载决议的目的,静态和非静态成员函数都具有隐式对象参数,但构造函数没有。

只有const限定的成员函数才能在const限定的对象参数上调用。

编译器如何知道这str是 const?好吧,你在Foo.

于 2013-09-12T09:05:52.933 回答
0

我的问题是 std::string 成员函数 begin() 如何识别它被调用的对象是 const 并因此返回一个 const_iterator。

begin()方法有一个重载,该重载是const合格的,返回一个const_iterator. const合格意味着它是在调用它的对象时使用的那个const

iterator begin();
const_iterator begin() const;  // This one

使用strbeing const,第二个被调用,因此返回的对象是 a const_iterator,您尝试分配给一个iterator无效的对象,从而导致错误。


我可以更改或以某种方式重载类成员函数以在被 const 对象调用时采取不同的行为吗?

使用auto!而不是做

std::string::iterator start;

start = str.begin();

auto start = str.begin();

这样,您实际上使用的begin().

但是,您可能会以错误的方式做事,因为您是否需要 const 或非常量迭代器取决于您要完成的任务。作为一般准则,除非您打算修改容器内的元素,否则请始终使用 const 迭代器。

于 2013-09-12T09:05:45.263 回答
0

如果您的对象是 const,编译器会自动选择一个 const 成员函数。

您必须提供两个成员函数:

void someMethod();
void someMethod() const;
于 2013-09-12T09:07:38.930 回答