Apr 21, 2013 at 2:16am UTC
I am beyond confused now with temporaries, lvalues and rvalues. I understand the difference but exactly what are temporaries? Some people say there are rvalues, some say everything is a temporary because every object is destroyed at one point or another...
Apr 21, 2013 at 2:30am UTC
(motto1 = motto2) = motto3;
This means that the temporary gets the the value of motto3 and I cannot refer to the temporary because it doesn't have a "name/identifier"?
Apr 21, 2013 at 2:57am UTC
Temporaries are unnamed objects which expire at the end of the full expression they're a part of.
In
(motto1 = motto2) = motto3;
there are actually two temporaries. There are two calls to operator= and each returns a temporary object.
This means that the temporary gets the the value of motto3 and I cannot refer to the temporary because it doesn't have a "name/identifier"?
You cannot refer to it outside of the full expression which defines its lifetime, but if you wanted to "show" the last temporary constructed:
((motto1 = motto2) = motto3).ShowIt();
would work.
Observing the output of the following might be helpful.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
#include <iostream>
#include <string>
class Verbose
{
public :
friend std::ostream& operator <<(std::ostream& os, const Verbose& v) ;
Verbose() : _id(_nextID++)
{ std::cout << *this << " constructed via default constructor.\n" ; }
Verbose(const std::string& s) : _id(_nextID++), _data(s)
{ std::cout << *this << " constructed via std::string constructor.\n" ; }
Verbose( const Verbose& v ) : _id(_nextID++), _data(v._data)
{ std::cout << *this << " constructed via copy constructor from " << v << ".\n" ; }
~Verbose()
{
std::cout << *this << " destroyed.\n" ;
}
Verbose operator =(const Verbose& v)
{
std::cout << *this << " = " << v << '\n' ;
_data = v._data ;
return *this ;
}
private :
const unsigned _id ;
std::string _data ;
static unsigned _nextID ;
};
std::ostream& operator <<(std::ostream& os, const Verbose& v )
{
return os << "Verbose #" << v._id << " (\"" << v._data << "\")" ;
}
unsigned Verbose::_nextID = 1 ;
int main()
{
Verbose motto1("The devil takes care of his own" ); // Verbose #1
Verbose motto2; // Verbose #2
Verbose motto3; // Verbose #3
std::cout << "---- Before temporary expression ----\n" ;
(motto1 = motto2) = motto3 ; // Verbose #4 and #5 are temporaries.
std::cout << "---- After temporary expression ----\n" ;
return 0;
}
[Edit: Modified code to show destructor calls.
http://ideone.com/qclnon ]
Last edited on Apr 21, 2013 at 3:24am UTC
Apr 21, 2013 at 2:59am UTC
Thanks cire, once again you are one of the best on this forum :D
Apr 21, 2013 at 4:26pm UTC
Also based on this I can conclude that my author was wrong? right?