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;
}


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