C++ Returning reference to temporary [duplicate]

2020-03-01 08:25发布

Possible Duplicate:
warning: returning reference to temporary

I am getting the error "returning reference to temporary" on the second line below.

class Object : public std::map <ExString, AnotherObject> const {
public:
const AnotherObject& Find (const ExString& string ) const {
  Object::const_iterator it = find (string);
  if (it == this->end()) { return AnotherObject() };
  return ( it->second );
}
}

My class implements std::map.

I am new to C++ so I'm guessing its just a syntax error. Any help?

8条回答
不美不萌又怎样
2楼-- · 2020-03-01 08:31

If your function looks like this:

AnotherObject& getAnotherObject()
{

    . . .

    Object::const_iterator it = find ("lang");
    if (it == this->end()) { return AnotherObject() };

    . . .

}

the problem is that the AnotherObject() you've returned will be destroyed as soon as the function exits, and so the caller to your function will have a reference to a bogus object.

If your function returned by value however:

AnotherObject getAnotherObject()

then a copy will be made before the original is destroyed and you'll be OK.

查看更多
淡お忘
3楼-- · 2020-03-01 08:34

You shouldn't return a reference to a temporary which is destroyed at the end of the line, nor a reference to a local which is destroyed at the end of the function.

If you want to keep the current signature, you'd have to add a static constant instance that you can return as a default.

#include <iostream>

template <class T>
class X
{
    T value;
    static const T default_instance;
public:
    X(const T& t): value(t) {}
    const T& get(bool b) const
    {
        return b ? value : default_instance;
    }
};

template <class T>
const T X<T>::default_instance = T();

int main()
{
    X<int> x(10);
    std::cout << x.get(true) << ' ' << x.get(false) << '\n';
}

You may also return by value or return a pointer in which case you can return NULL.

查看更多
家丑人穷心不美
4楼-- · 2020-03-01 08:37

You should change the return type of your function from "AnotherObject&" to "AnotherObject" and return that object by value. Otherwise it will go just like Blindy described

查看更多
走好不送
5楼-- · 2020-03-01 08:41

The call to AnotherObject's constructor creates a new instance on the stack, which is immediatly destroyed when the method returns.

It is most likely not a good idea to create and return new object if the find fails. The calling code will have no way to tell if the object returned is a previously existing object present in the data structure.

If you do want to do this, then you should add the new object to the data structure and then return an iterator pointing to the new object IN THE DATA STRUCTURE.

Something like this:

if (it == this->end()) {
    it = this->insert(pair<ExString, AnotherObject>( string, AnotherObject() ));
    return  it->second; 
}    
查看更多
男人必须洒脱
6楼-- · 2020-03-01 08:48

I personally think that this is a bit of a hack, but as long as you really stick to the const'ness of the returned reference you should be able to return a statically constructed instance of AnotherObject whose only "raison d'etre" is to be the "not found" return value of your function. Make it a static const private member of your class Object for example, and you should be ok as long as a default constructed instance of AnotherObject is not a valid value to be contained in an instance of Object.

查看更多
疯言疯语
7楼-- · 2020-03-01 08:49

You're creating a temporary value on the stack AnotherObject() and returning it right before it gets destroyed. Your function's caller would get garbage, and so it's forbidden.

Maybe you want to allocate it on the heap and return a pointer to it instead?

return new AnotherObject();

Alternatively, declare your function to return a "copy" to your object, instead of a reference like I'm assuming you are returning right now:

AnotherObject f()
{
  return AnotherObject();  // return value optimization will kick in anyway!
}
查看更多
登录 后发表回答