简体   繁体   中英

C++ “warning: returning reference to temporary ” - But it isn't

I have a very simple method, and const overload of it.

Sy_animatable::PropertyTimeLine&
Sy_animatable_imp::getPropertyTimeLine( const QString& property )
{
    if ( !properties_.contains( property ) ) {
        throw Sy_unknownAnimPropertyException( property );
    }

    return properties_[property];
}

const Sy_animatable::PropertyTimeLine&
Sy_animatable_imp::getPropertyTimeLine( const QString& property ) const
{
    if ( !properties_.contains( property ) ) {
        throw Sy_unknownAnimPropertyException( property );
    }

    return properties_[property];  // "warning: returning reference to temporary"
}

I don't understand the warning for two reasons:

  1. properties_ is a member variable and it's subscript operator (it's a QMap ) returns a reference, so there shouldn't be any temporaries and it is persistant for the lifetime of the object.
  2. Why is the warning appearing in the const overload and not the original?

I could #pragma the line to hide the warning, but I really want to know why it is giving me the warning - any suggestions?

Looks like the [] -operator for QMap has strange semantics that sometimes generate a const-reference to a temporary (if there's no element with the given key), and the lifetime of that one isn't extended far enough.

Try return properties_.find(property).value(); instead.

In QMap, operator[]() is kind of quirky; it can both insert (key, value) pairs in the map, and be used for looking up a value. The documentation states:

To look up a value, use operator or value():

 int num1 = map["thirteen"]; int num2 = map.value("thirteen"); 

If there is no item with the specified key in the map, these functions return a default-constructed value.

QMap::value() returns a default-constructed value if the specified key isn't in the map -- which means a value is created using the default constructor. This is the temporary the warning you are getting is referring to. While operator[]() will not silently insert a (key, value) pair if it already exists (but will if it doesn't), using .value() is the way to go although I'm not sure the warning will go away.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM