#include <iostream>
using namespace std;
template <typename T, typename U>
T&& Forward(U&& arg) {
return static_cast<T&&>(arg);
}
class Container
{
int data_;
public:
explicit Container(int data = 1) // Set the data variable
: data_(data) {}
~Container() {data_ = -1;} // When destructed, first set the data to -1
void test()
{
if (data_ <= 0)
std::cout << "OPS! A is destructed!\n";
else
std::cout << "A = " << data_ << '\n';
}
};
// This class has a reference to the data object
class Reference_To_Container_Wrapper
{
const Container& a_;
public:
explicit Reference_To_Container_Wrapper(const Container& a) : a_(a) {}
// (I) This line causes problems! This "Container" returned will be destroyed and cause troubles!
const Container get() const {return a_;} // Build a new Container out of the reference and return it
};
template <class T>
struct ReferenceContainer
{
T should_be_valid_lvalue_ref;
template <class U> // U = Reference_To_Container_Wrapper
ReferenceContainer(U&& u) :
// We store a l-value reference to a container, but the container is from line (I)
// and thus will soon get destroyed and we'll have a dangling reference
should_be_valid_lvalue_ref(Forward<T>(std::move(u).get())) {}
};
int main() {
Container a(42); // This lives happily with perfect valid data
ReferenceContainer<const Container&> rc( (Reference_To_Container_Wrapper(a)) ); // Parenthesis necessary otherwise most vexing parse will think this is a function pointer..
// rc now has a dangling reference
Container newContainer = rc.should_be_valid_lvalue_ref; // From reference to Container
newContainer.test();
return 0;
}