I get dangling links when using a loop for a range. Consider the following C ++ 14 expression (full program example below):
for(auto& wheel: Bike().wheels_reference()) wheel.inflate();
At the exit:
Wheel() Wheel() Bike() ~Bike() with 0 inflated wheels. ~Wheel() ~Wheel() Wheel::inflate() Wheel::inflate()
Obviously, something is very wrong. Wheels are accessible outside their life, and the result is 0, not expected.
An easy fix is ββto enter a variable for Bike
in main
. However, I do not control the code in main
or Wheel
. I can change the structure of the Bike
.
Is there a way to fix this example just by changing Bike
?
A successful solution will either fail at compile time, or score 2 inflated tires and not touch any objects outside of their lives.
Application: ready-made compilation source code
#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; }
Remco source share