Std::shared_ptr不能使用range for
std::shared_ptr not working with range for
我正在尝试迭代一个范围内的临时对象for循环。看起来对象在循环开始执行之前就被销毁了。这是标准的合规行为吗?我使用的是gcc 4.8。
#include <iostream>
#include <vector>
#include <memory>
struct Test: std::vector<int> {
Test(): std::vector<int>{1,2,3} {
std::cout << __PRETTY_FUNCTION__ << 'n';
}
~Test() {
std::cout << __PRETTY_FUNCTION__ << 'n';
}
};
std::shared_ptr<Test> func() {
return std::shared_ptr<Test>(new Test);
}
int main() {
for (const auto &obj: *func()) {
std::cout << obj << 'n';
}
}
结果如下:
Test::Test()
Test::~Test()
21770300
0
33
0
0
0
3
是,行为是兼容的。
c++ 11标准第6.5.4/1段:
对于形式为
的基于范围的for
语句for ( for-range-declaration : expression ) statement
让range-init等价于用圆括号括起来的表达式
( expression )
和形式为
的基于范围的for
语句for ( for-range-declaration : braced-init-list ) statement
让range-init等价于带括号的init-list。在每种情况下,基于范围的for语句都相当于
{ auto && __range = range-init; for ( auto __begin = begin-expr, __end = end-expr; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
在你的例子中,返回的共享指针被解引用,它指向的对象被绑定到__range
引用。但是,共享指针本身不会被复制,也不会绑定到会延长其生命周期的引用。因此,它超出了范围。作为引用指向对象的最后一个共享指针,该对象也被销毁。
如果您按值返回Test
对象,而不是返回共享指针,情况将会有所不同:
Test func() {
return Test();
}
int main() {
for (const auto &obj: func()) {
std::cout << obj << 'n';
}
}
这样,func()
返回的Test
临时值绑定到__range
引用,并且它的生存期被延长以匹配引用的生存期。
下面是一个的实例
相关文章:
- 迭代的"range-based for"召唤
- c++ 中的 range-for 会调用项的复制构造函数吗?
- C++ 通过 range for 循环将整数输入到矢量中;随机 0
- C++11 语法'type var : var'称为'range-based for'
- 删除for-range循环中项目的最快方法
- 为什么 range-for 找不到 std::istream_iterator 的开始和结束重载?
- C++11:基于范围的 for 语句:"range-init"生命周期?
- Range-for-loops 和 std::vector<bool>
- 如何在range for循环中使用begin()和end()
- 为什么不能在range-base for中使用迭代器
- 制作可互换的向前/向后for-range迭代器
- 强制auto为range for循环中的引用类型
- 使用 range-for 循环:函数调用的参数太少,未指定单个参数'a'
- 如何使我的自定义类型与"range-based for loops"一起使用?
- Std::shared_ptr不能使用range for
- range -for语句不能使用数组函数参数构建范围表达式
- 从整数索引的for循环枚举到range-for
- 便携地支持轻松的range-for-loop
- 我应该在什么时候使用新的range -for,以及我可以将它与新的cbegin/cend结合使用吗?
- 使用c++ 11基于范围的for循环和右值range-init是否安全?