A durable link must be bound to an lvalue . In principle, as you so eloquently put it, an object having a specific address. If they are tied to a temporary, the temporary will be destroyed while the link still refers to it, and the results are undefined.
Short-lived const links (local function variables and function arguments) can be tied to temporary ones. If they are, a temporary one is guaranteed that it will not be destroyed until the link goes beyond.
Demo Code:
#include <iostream> class Big { public: Big() : living_(true), i_(5) { // This initialization of i is strictly legal but void *me = this; // the result is undefined. ::std::cerr << "Big constructor called for " << me << "\n"; } ~Big() { void *me = this; living_ = false; ::std::cerr << "Big destructor called for " << me << "\n"; } bool isLiving() const { return living_; } const int &getIref() const; const int *getIptr() const; private: ::std::string s_; bool living_; const int &i_; char stuff[50]; }; const int &Big::getIref() const { return i_; } const int *Big::getIptr() const { return &i_; } inline ::std::ostream &operator <<(::std::ostream &os, const Big &b) { const void *thisb = &b; return os << "A " << (b.isLiving() ? "living" : "dead (you're lucky this didn't segfault or worse)") << " Big at " << thisb << " && b.getIref() == " << b.getIref() << " && *b.getIptr() == " << *b.getIptr(); } class A { public: A() : big_(Big()) {} const Big &getBig() const { return big_; } private: const Big &big_; }; int main(int argc, char *argv[]) { A a; const Big &b = Big(); const int &i = 0; ::std::cerr << "a.getBig() == " << a.getBig() << "\n"; ::std::cerr << "b == " << b << "\n"; ::std::cerr << "i == " << i << "\n"; return 0; }
And the conclusion:
Big constructor called for 0x7fffebaae420 Big destructor called for 0x7fffebaae420 Big constructor called for 0x7fffebaae4a0 a.getBig() == A living Big at 0x7fffebaae420 && b.getIref() == -341121936 && *b.getIptr() == -341121936 b == A living Big at 0x7fffebaae4a0 && b.getIref() == 0 && *b.getIptr() == 0 i == 0 Big destructor called for 0x7fffebaae4a0
Omnifarious
source share