简体   繁体   English

从常量成员函数返回迭代器

[英]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::funcvector<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* ,所以部件的类型arstd::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指向其数据成员之一,因此,如果函数为constiterator必须为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM