它按预期工作的示例
#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;
}
在这段代码中,我得到以下输出:
0 0 0 0 0 0 0 0
一个不能按预期工作的例子:
#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"
第一个代码示例
它有一个问题,我调用(错误地)向量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;
}
我在第8和第12行收到以下警告:
returning reference to local temporary object [-Wreturn-stack-address] [cpp/gcc]
但是当我编译并运行程序时,我得到:
0 0 0 0 0 0 0 0
因此,它似乎在返回myvec.begin()时不会销毁本地引用.当我第一次编写代码时,我并不认为它会成为一个问题,因为在我的脑海中,来自向量的begin()方法将返回对第一个向量位置的迭代器引用,这个迭代器对我来说不是当我执行myvec.begin()时分配,但是是对此迭代器的引用.所以,这个警告不应该出现,因为我没有分配内存.但由于我不知道这种机制是如何工作的,我想学习它来编写一致的代码.看来我可以忽略这个警告,不是吗?
最佳答案 std :: vector :: begin确实返回一个临时对象
(见
http://www.cplusplus.com/reference/vector/vector/begin/)
您的代码是有效的,因为您将临时对象绑定到const引用(对于非const引用不合法),并立即将其复制到局部变量中.
编辑:我的错误.这确实也是UB从临时返回一个const引用.
但是,将此引用分配给具有更长生命周期的另一个const引用将导致未定义的行为,因为临时对象的生命周期仅扩展到它直接分配给它的const引用的生命周期.
我建议考虑警告并返回迭代器.
我还建议阅读http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/