user1330092
user1330092

Reputation:

C++ Return a local or temp variable

Hi guys some problem here:

here is my overloaded operator :

const double & Waz::operator()(int i,int j) const
{
return ((WazImpl const)(*p))(i,j);
}

Where in Waz class I have : WazImpl* p; and in the class WazImpl I have an operator ()

The warning is : Warning C4172 returning address of local variable or temporary

As far as I understand I'm returning a temp variable which is destroyed somewhere else what can I do to fix it?

Thanks!

Upvotes: 1

Views: 1621

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 311048

You have two possibilities. The first one is to return simply double instead of the reference const double &

double Waz::operator()(int i,int j) const
{
   return ((WazImpl const)(*p))(i,j);
}

The second one is to return the reference to the original value provided that the called operator also returns const reference to double

const double & Waz::operator()(int i,int j) const
{
   const double &rd = (WazImpl const)(*p))(i,j );

   return rd;
}

Here is a simple example that demonstrates the second approach

#include <iostream>

struct A
{
    int & operator ()(){ return a; }
    int a = 10;
};

struct B : A
{
    int & operator ()()
    {
        int &ri = A::operator ()();
        return ri;
    }
};

int main() 
{
    B b;

    b() = 20;

    std::cout << b.a << std::endl;


    return 0;
}

Upvotes: 1

log0
log0

Reputation: 10937

You should show us the implementation of WazImpl but it seems that WazImpl::operator() const returns a double.

It means that ((WazImpl const)(*p))(i,j) returns a temporary (it exists only in the scope of Waz::operator()).
As Waz::operator() returns a double &, you are indeed returning a reference to a temporary.

Either you are returning a temporary value that just got computed in WazImpl::operator() then you should return a double in Waz::operator() either you are really returning a reference to an existing double in WazImpl and you should fix the signature of WazImpl::operator() const so that it returns a const double&.

Upvotes: 0

Felix Glas
Felix Glas

Reputation: 15534

If you dissect the function you can see that it is equivalent to the following:

const double& Waz::operator()(int i, int j) const {
    // Cast pointer to callable.
    const WazImpl& wi = static_cast<const WazImpl>(*p);

    // Get result of calling callable.
    double d = wi(i, j);

    // Return REFERENCE to local object.
    return d;
} // All local objects is destroyed and references to them become dangling.

So, you indeed get a dangling reference when calling your Waz::operator.

One solution is to return by value which will return a copy of the result. Also don't return by const value as it makes little sense.

double Waz::operator()(int i, int j) const;

Upvotes: 3

Related Questions