[英]Returning iterator from constant member function
In the following code why the return type of foo::func
is vector<int>::const_iterator
and not vector<int>::iterator
though I am returning an object of vector<int>::iterator
. 在下面的代码为什么的返回类型
foo::func
是vector<int>::const_iterator
而不是vector<int>::iterator
虽然我回来的目的vector<int>::iterator
。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class foo
{
private:
vector<int> ar;
public:
foo()
{
ar.resize(10);
iota(ar.begin(), ar.end(), 1);
}
auto func() const
{
return ar.begin() + 5;
}
};
int main()
{
foo x;
cout<<boolalpha<<endl;
auto it = x.func();
cout<<is_same<decltype(it), vector<int>::iterator>::value<<endl;
cout<<is_same<decltype(it), vector<int>::const_iterator>::value<<endl;
return 0;
}
Output of above code is : 上面代码的输出是:
false
true
Instead if I redefine foo::func()
as 相反,如果我将
foo::func()
重新定义为
auto func()
{
return ar.begin() + 5;
}
The output will be 输出将是
true
false
Why the constant member function is changing return type to constant? 为什么常量成员函数将返回类型更改为常量? And should I need to remove
const
keyword to make the return type as vector<int>::iterator
or is there any other way? 并且我是否需要删除
const
关键字以使返回类型为vector<int>::iterator
或还有其他方法吗?
A member function declared const
affects the type of the this
pointer. 声明为
const
的成员函数会影响this
指针的类型。 Within func()
, this
has type const foo*
. 在
func()
, this
类型为const foo*
。 As a result, all member types accessed via a const
this
pointer will themselves be const
, so the implicit type of ar
is in fact const std::vector<int>
. 结果,通过
this
指针const
访问的所有成员类型本身将为const
,因此ar
的隐式类型实际上是const std::vector<int>
。 Of the two begin()
overloads for vector
, the only viable overload is the const
overload, which returns a const_iterator
. vector
的两个begin()
重载中,唯一可行的重载是const
重载,它返回const_iterator
。
When you redefine func()
to be non- const
, then the type of this
is simply foo*
, so the type of the member ar
is std::vector<int>
and the overload of begin()
returning iterator
is preferred. 当重新定义
func()
成非const
,那么类型this
简单地foo*
,所以部件的类型ar
是std::vector<int>
和的过载begin()
返回iterator
是优选的。
There are two std::vector::begin
depending on whether the instance is const
or not. 根据实例是否为
const
有两个 std::vector::begin
。
In foo::func() const
, you are trying to access ar
which is then viewed as a const std::vector<int>
, and std::vector::begin() const
returns a const_iterator
. 在
foo::func() const
,您尝试访问ar
,然后将其视为const std::vector<int>
,而std::vector::begin() const
返回const_iterator
。
When you access ar
in foo::func()
, it is then viewed as a std::vector<int>
, without const
, and begin
will then refer to std::vector::begin()
(without const
again), which is not the same function. 当您在
foo::func()
访问ar
时,它将被视为std::vector<int>
,而没有const
,然后begin
将引用std::vector::begin()
(再次没有const
),这是不一样的功能
Similarly, your own foo
class could define two versions of foo::func
simultaneously: 同样,您自己的
foo
类可以同时定义foo::func
两个版本:
auto func()
{ return ar.begin() + 5; }
auto func() const
{ return ar.begin() + 5; }
And the constness of the instances will decide which version to call: 实例的常数将决定调用哪个版本:
foo x;
const foo y;
x.func(); // First version, get an iterator
y.func(); // Second version, get a const_iterator
The iterator
points to one of its data members and so if the function is const
then the iterator
must be const
too otherwise you could change the data contained in the class
from the iterator
returned by a const
member function. iterator
指向其数据成员之一,因此,如果函数为const
则iterator
必须为const
否则您可以从const
成员函数返回的iterator
更改class
包含的数据。
That's my understanding at least - I would be grateful if someone else could confirm or deny this. 至少这是我的理解-如果其他人可以确认或否认这一点,我将不胜感激。
Member function begin
is overloaded the following way 成员函数
begin
按以下方式重载
iterator begin() noexcept;
const_iterator begin() const noexcept;
Thus functions that are declared with qualifier const
deal with constant objects. 因此,用限定符
const
声明的const
处理常量对象。 That means that data members of a constant object if they are not declared as mutable
are also constant. 这意味着,如果常量对象的数据成员未声明为
mutable
则它们也是常量。 In this case the second overloaded function begin
is called for data member ar
that returns const_iterator
. 在这种情况下,将为返回
const_iterator
数据成员ar
调用第二个重载函数begin
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.