Re: [eigen] Very interesting read which might be important for us |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
Hauke Heibel wrote:
Well, at least from a programmers point of view.
http://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
- Hauke
Interesting. Unfortunately this const-reference-to-a-temporary seems to
be limited to immediate stack variables, not stack structures that have
const-refs inside them.
I hoped this might allow one to create a lightweight reference that
could be passed around. See attached file.
The tests 3&4 did not behave as I expected. I think what I was hoping
for is not possible with automatic variables. The output from the
program (linux x86_64, gcc 4.1.2) is:
[markb@hedy ~]$ g++ -Wall -O2 -o test_const_retval test_const_retval.cc
&& ./test_const_retval
test 1: return by value:
BigExpensiveObject default constructor
BigExpensiveObject being used
BigExpensiveObject destructor
test 2:grab const ref to a temporary
BigExpensiveObject default constructor
BigExpensiveObject being used
BigExpensiveObject destructor
test 3:proxy object created from function returning temporary
BigExpensiveObject default constructor
ConstRef constructor
BigExpensiveObject destructor
BigExpensiveObject being used
ConstRef destructor
test 4:proxy object
BigExpensiveObject default constructor
ConstRef constructor
BigExpensiveObject destructor
BigExpensiveObject being used
ConstRef destructor
#include <iostream>
using namespace std;
struct BigExpensiveObject
{
BigExpensiveObject(){ cout << "BigExpensiveObject default constructor\n"; }
~BigExpensiveObject() { cout << "BigExpensiveObject destructor\n"; }
BigExpensiveObject(const BigExpensiveObject & other ){ cout << "BigExpensiveObject copy constructor\n"; }
void Use() const { cout << "BigExpensiveObject being used\n"; }
};
struct ConstRef
{
const BigExpensiveObject & ref;
ConstRef( const BigExpensiveObject & beo) : ref(beo) {cout << "ConstRef constructor\n";}
ConstRef( const ConstRef & other) : ref(other.ref) {cout << "ConstRef copy constructor\n";}
~ConstRef() {cout << "ConstRef destructor\n";}
operator const BigExpensiveObject & () const {return ref;}
};
BigExpensiveObject simple_return_value()
{
BigExpensiveObject beo;
return beo;
}
ConstRef proxy_return_value()
{
BigExpensiveObject beo;
return ConstRef(beo);
}
int main(int argc,char ** argv)
{
cout << "\ntest 1: return by value:\n";
{
BigExpensiveObject beo = simple_return_value();
beo.Use();
}
cout << "\ntest 2:grab const ref to a temporary\n";
{
const BigExpensiveObject & beo = simple_return_value();
beo.Use();
}
cout << "\ntest 3:proxy object created from function returning temporary\n";
{
ConstRef p = simple_return_value();
// AAARGH! the destructor gets called here, leaving a dangling reference
p.ref.Use();
}
cout << "\ntest 4:proxy object\n";
{
ConstRef p = proxy_return_value();
// AAARGH! the destructor gets called here, leaving a dangling reference
p.ref.Use();
}
return 0;
}