Reputation: 22346
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:
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.I could #pragma
the line to hide the warning, but I really want to know why it is giving me the warning - any suggestions?
Upvotes: 2
Views: 932
Reputation: 40830
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.
Upvotes: 2
Reputation: 476990
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.
Upvotes: 8