Re: [eigen] Very interesting read which might be important for us

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


Yeah, this is also mentioned in one of the comments of the article.
The comment starts with

"That’s not the Guru question, the guru question what is the exception
to this rule?"

- Hauke

On Wed, May 19, 2010 at 4:34 PM, Mark Borgerding <mark@xxxxxxxxxxxxxx> wrote:
> 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;
> }



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/