C++ 返回C++;迭代器引用 它确实按预期工作的示例 一个不按预期工作的示例: 第一个代码示例

C++ 返回C++;迭代器引用 它确实按预期工作的示例 一个不按预期工作的示例: 第一个代码示例,c++,vector,reference,iterator,C++,Vector,Reference,Iterator,它有一个问题,我(错误地)调用了向量begin()和end(),而不是MyClass方法 我有以下最低限度的代码来表示我的怀疑: #include <iostream> #include <vector> struct MyClass{ const std::vector<float>::iterator& begin(){ return myvec.begin(); } const std::vector<float

它有一个问题,我(错误地)调用了向量
begin()
end()
,而不是MyClass方法

我有以下最低限度的代码来表示我的怀疑:

#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;
}
但当我编译并运行程序时,我得到:

0 0 0 0 0 0 0 0 

因此,当本地引用返回
myvec.begin()
时,它似乎没有被销毁。当我第一次编写代码时,我并不认为这会是一个问题,因为在我的头脑中,向量中的begin()方法将返回对第一个向量位置的迭代器引用,在我执行myvec.begin()时,没有分配这个迭代器,而是对这个迭代器的引用。所以,这个警告不应该出现,因为我没有分配内存。但因为我不知道这个机制是如何工作的,所以我想学习它来编写一致的代码。看来我可以忽略这个警告,不是吗

std::vector::begin确实返回一个临时对象 (见附件)

您的代码是有效的,因为您正在将临时对象绑定到常量引用(非常量引用不合法),并立即将其复制到局部变量
it

编辑:我的错误。这实际上也是从临时文件返回常量引用的一种方法

但是,将此引用分配给另一个具有较长生存期的常量引用将导致未定义的行为,因为临时对象的生存期仅扩展到直接分配给它的常量引用的生存期

我建议考虑警告并返回迭代器


我还建议您阅读

您是从哪里知道
begin()
返回一个引用的?您在哪里看到任何引用结果?它返回一个对象。@Werner:你想知道为什么未定义的行为不能给出定义良好的行为吗?因为它没有定义。(在这种情况下,这可能只是意味着被破坏对象的存储在被复制到局部变量之前没有被重用,因此它仍然包含旧值。不过,你不能依赖这种行为。)@Werner:事实上,在对象的生命周期结束后使用它总是很困难的,返回对自动变量或临时变量的引用总是错误的。一旦程序的生命周期结束,就没有(可移植的)方法来阻止它重用内存。您需要按值返回迭代器。仅供参考,实际调用的代码是有效的,因为您从未调用
MyClass
begin()
end()
成员。相反,您可以直接调用
myClass.myvec.begin()
myClass.myvec.end()
。你的会员没有资格。我会看推荐信的!这似乎正是我需要的补充。然而,我仍然觉得const引用(即使临时对象的跨度时间有限)正是示例中所需要的…我不相信这是正确的。const引用必须至少与煽动的临时引用在同一范围内(在所有链接文章示例中,Herb都将其表示为有效)。这里的情况并非如此。一旦被调用的函数返回,临时函数肯定会消失。本标准第12.2/5节【临时类】对此进行了描述,但肯定不是用最简单的术语。如果这不是一个准确的评估,那么我从const reference中学到的关于临时寿命延长的所有知识都消失了。加上第三段,这似乎是正确的,因此+1。
#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;
}
"empty output"
#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;
}
returning reference to local temporary object [-Wreturn-stack-address] [cpp/gcc] 
0 0 0 0 0 0 0 0