简体   繁体   English

返回C ++迭代器引用

[英]Return C++ iterator reference

Example in which it does work as expected 它按预期工作的示例

#include <iostream>
#include <vector>

struct MyClass{


  const std::vector<float>::iterator& begin(){
    return myvec.begin();
  }

  const std::vector<float>::iterator& end(){
    return myvec.end();
  }
  std::vector<float> myvec;
};

int main(){

  std::vector<float> mainvec(8,0);

  MyClass myClass;

  myClass.myvec = mainvec;

  for (std::vector<float>::iterator it = myClass.begin();
      it != myClass.end();++it){
    std::cout << *it << " " ;
  }

  std::cout << std::endl;
}

In this code I get the following output: 在这段代码中,我得到以下输出:

0 0 0 0 0 0 0 0 

An example which does NOT works as expected: 一个不能按预期工作的例子:

#include <iostream>
#include <vector>

struct MyClass{


  const std::vector<float>::iterator& begin(){
    return myvec.begin();
  }

  const std::vector<float>::iterator& end(){
    return myvec.end();
  }
  std::vector<float> myvec;
};

int main(){

  std::vector<float> mainvec(8,0);

  MyClass myClass;

  myClass.myvec = mainvec;

  const std::vector<float>::iterator& end_reference = myClass.end();

  for (std::vector<float>::iterator it = myClass.begin();
      it != end_reference;++it){
    std::cout << *it << " " ;
  }

  std::cout << std::endl;
}

In this code I get the following output: 在这段代码中,我得到以下输出:

"empty output"

The first code example 第一个代码示例

It has the problem in which I invoke (erroneously) the vector begin() and end() instead of MyClass methods. 它有一个问题,我调用(错误地)向量begin()end()而不是MyClass方法。

I have the following minimal code to represent my doubt: 我有以下最小代码来表示我的疑问:

#include <iostream>
#include <vector>

struct MyClass{


  const std::vector<float>::iterator& begin(){
    return myvec.begin();
  }

  const std::vector<float>::iterator& end(){
    return myvec.end();
  }
  std::vector<float> myvec;
};

int main(){

  std::vector<float> mainvec(8,0);

  MyClass myClass;

  myClass.myvec = mainvec;

  for (std::vector<float>::iterator it = myClass.myvec.begin();
      it != myClass.myvec.end();++it){
    std::cout << *it << " " ;
  }

  std::cout << std::endl;
}

I get the following warnings on lines 8 and 12: 我在第8和第12行收到以下警告:

returning reference to local temporary object [-Wreturn-stack-address] [cpp/gcc] 

but when I compile and run the program, I get: 但是当我编译并运行程序时,我得到:

0 0 0 0 0 0 0 0 

So, it seems that the local reference is not destroyed when it returns the myvec.begin() . 因此,它似乎在返回myvec.begin()时不会销毁本地引用。 When I first wrote the code, I didn't thought it was going to be a problem, as in my head the begin() method from the vector would return a iterator reference to the first vector place, this iterator for me is not being allocated when I do myvec.begin(), but is a reference to this iterator. 当我第一次编写代码时,我并不认为它会成为一个问题,因为在我的脑海中,来自向量的begin()方法将返回对第一个向量位置的迭代器引用,这个迭代器对我来说不是当我执行myvec.begin()时分配,但是是对此迭代器的引用。 So, this warning shouldn't appear, as I am not allocating memory. 所以,这个警告不应该出现,因为我没有分配内存。 But since I don't know how this mechanism works, I would like to learn it for writing consistent code. 但由于我不知道这种机制是如何工作的,我想学习它来编写一致的代码。 It seems that I can ignore this warning, can't I? 看来我可以忽略这个警告,不是吗?

std::vector::begin returns indeed a temporary object (see http://www.cplusplus.com/reference/vector/vector/begin/ ) std :: vector :: begin确实返回一个临时对象(参见http://www.cplusplus.com/reference/vector/vector/begin/

Your code is valid since you are binding the temporary object to a const reference (would not be legal with a non const reference), and copy it right away in a local variable it . 你的代码是有效的,因为你的临时对象绑定到一个const引用(不合法与非const引用),并在一个局部变量拷贝它的时候了it
edit: My mistake. 编辑:我的错误。 This is indeed also UB to return a const reference from a temporary. 这确实也是UB从临时返回一个const引用。

However assigning this reference to another const reference with a longer lifetime would result in undefined behavior as the lifetime of a temporary object is only extended to the lifetime of the const reference it is directly assigned to. 但是,将此引用分配给具有更长生命周期的另一个const引用将导致未定义的行为,因为临时对象的生命周期仅扩展到它直接分配给它的const引用的生命周期。

I would recommend taking into account the warning and return an iterator. 我建议考虑警告并返回迭代器。

I also recommend reading http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/ 我还建议阅读http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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