Nick
Nick

Reputation: 972

Correct way to convert rvalue reference to temporary parameter to const lvalue return in C++

I'm trying to implemenet find-like method to extract reference to value from container and return a default value if the value is not found or of an incompatible type.

template<class T> const T& get (key_type k, const T& def)
{
    const T* r = dynamic_cast<const T*> (find(k)); // suppose `find` returns a pointer to common base class or NULL if the key not found
    return r ? *r : def; 
}

this function works incorrectly if def is a temporary object:

const sometype& val = find(key, sometype(someargs));

So, is it possible to handle this case using rvalue reference and moving or copying the temporary object somehow?

template<class T> const T& get (key_type k, T&& def)
{
    const T* r = dynamic_cast<const T*> (find(k)); // suppose `find` returns a pointer to common base class or NULL if the key not found
    return r ? *r : std::move(def); // or copy? or something else?
}

Tmight be an abstract base class too. And, please, I'd prefer boost-free solution.

Upvotes: 1

Views: 549

Answers (1)

Jiho Park
Jiho Park

Reputation: 51

No, you can't. The temporary object is alive only for that statement and will be destroyed before you access it through the returned reference.

const sometype &val = get(not_existing_key, get_temporary_object());
do_something_with(val);

When you do_something_with(val), the object to which the reference val is bound is already destroyed. The get function should not called with a temporary object for the parameter def. Instead, you can copy the temporary object to a variable, then call the function with the reference to the variable.

auto copied_object = get_temporary_object();
const sometype &val = get(not_existing_key, copied_object);
do_something_with(val);

Now, the object to which val is bound is in the variable copied_object.

Upvotes: 1

Related Questions