【发布时间】:2016-01-14 11:53:58
【问题描述】:
我在使用 ranged-for 循环时得到了悬空引用。考虑以下 C++14 表达式(下面的完整示例程序):
for(auto& wheel: Bike().wheels_reference())
wheel.inflate();
它的输出是:
Wheel()
Wheel()
Bike()
~Bike() with 0 inflated wheels.
~Wheel()
~Wheel()
Wheel::inflate()
Wheel::inflate()
显然有些地方出了问题。轮子在其生命周期之外被访问,结果为 0,而不是预期的 2。
一个简单的解决方法是在main 中为Bike 引入一个变量。但是,我不控制main 或Wheel 中的代码。我只能更改结构Bike。
有什么方法可以通过只更改Bike 来解决这个例子吗?
一个成功的解决方案要么在编译时失败,要么计算 2 个充气轮胎并且在其生命周期之外不接触任何对象。
附录:编译准备好的源码
#include <cstdlib>
#include <iostream>
#include <array>
#include <algorithm>
using std::cout;
using std::endl;
struct Wheel
{
Wheel() { cout << " Wheel()" << endl; }
~Wheel() { cout << "~Wheel()" << endl; }
void inflate() { inflated = true; cout << " Wheel::inflate()" << endl; }
bool inflated = false;
};
struct Bike
{
Bike() { cout << " Bike()" << endl; }
~Bike() {
cout << "~Bike() with " << std::count_if(wheels.begin(), wheels.end(),
[](auto& w) { return w.inflated; }) << " inflated wheels." << endl;
}
std::array<Wheel, 2>& wheels_reference() { return wheels; }
std::array<Wheel, 2> wheels{Wheel(), Wheel()};
};
int main()
{
for(auto& wheel: Bike().wheels_reference())
wheel.inflate();
return EXIT_SUCCESS;
}
【问题讨论】:
-
如果只在
Bike中,函数reference应该按值返回数组,而不是按引用,但我认为,这不是你想要的。 -
@ForEveR 但
auto&无法绑定。 -
@ForEveR:虽然它解决了销毁后使用,但它不满足我的解决条件。打印的值为 0,而不是 2。
-
@TartanLlama 但同时在 gcc/clang 中绑定。
-
@ForEveR 呵呵,我猜是大脑编译器坏了。
标签: c++ reference c++14 ranged-loops