fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. template <typename T, typename U>
  5. T&& Forward(U&& arg) {
  6. return static_cast<T&&>(arg);
  7. }
  8.  
  9. class Container
  10. {
  11. int data_;
  12. public:
  13. explicit Container(int data = 1) // Set the data variable
  14. : data_(data) {}
  15. ~Container() {data_ = -1;} // When destructed, first set the data to -1
  16.  
  17. void test()
  18. {
  19. if (data_ <= 0)
  20. std::cout << "OPS! A is destructed!\n";
  21. else
  22. std::cout << "A = " << data_ << '\n';
  23. }
  24. };
  25.  
  26. // This class has a reference to the data object
  27. class Reference_To_Container_Wrapper
  28. {
  29. const Container& a_;
  30. public:
  31. explicit Reference_To_Container_Wrapper(const Container& a) : a_(a) {}
  32.  
  33. // (I) This line causes problems! This "Container" returned will be destroyed and cause troubles!
  34. const Container get() const {return a_;} // Build a new Container out of the reference and return it
  35. };
  36.  
  37. template <class T>
  38. struct ReferenceContainer
  39. {
  40. T should_be_valid_lvalue_ref;
  41.  
  42. template <class U> // U = Reference_To_Container_Wrapper
  43. ReferenceContainer(U&& u) :
  44. // We store a l-value reference to a container, but the container is from line (I)
  45. // and thus will soon get destroyed and we'll have a dangling reference
  46. should_be_valid_lvalue_ref(Forward<T>(std::move(u).get())) {}
  47. };
  48.  
  49. int main() {
  50.  
  51. Container a(42); // This lives happily with perfect valid data
  52. ReferenceContainer<const Container&> rc( (Reference_To_Container_Wrapper(a)) ); // Parenthesis necessary otherwise most vexing parse will think this is a function pointer..
  53. // rc now has a dangling reference
  54. Container newContainer = rc.should_be_valid_lvalue_ref; // From reference to Container
  55. newContainer.test();
  56.  
  57. return 0;
  58. }
Success #stdin #stdout 0s 3296KB
stdin
Standard input is empty
stdout
OPS! A is destructed!