2

Somewhere in my code I have a local std::unique_ptr<T>. I need to do stuff with the object pointed at, and I use a function for that:

std::unique_ptr<T> some_function( std::unique_ptr<T> &t )
{
    // do stuff
    return t;
}

I call the function like this:

std::unique_ptr<T> some_T_ptr( new T(/*args*/) );
vector_of_finalized_Ts.push_back( std::move(some_function(std::move(some_T_ptr))));

Now I wonder, is there a better way to get the necessary functionality? It just seems two moves are pretty superfluous and potentially dangerous. I do have error handling code I'm not showing here, but that's beside the point.

4

3 回答 3

4

It is all about ownership. Do you want some_function to take ownership of the pointer or not? If not, you can just pass a raw pointer to some_function. If you want some_function to take ownership (and return ownership), then it should take the unique_ptr by value. Otherwise the return statement (which should be std::move(t)) will be moving from a reference of unknown origins.

std::unique_ptr<T> some_function( std::unique_ptr<T> t )
{
    // I own t here and will delete it if an exception happens
    // do stuff
    // I'm transferring ownership back to the caller
    //     (who may or may not accept ownership)
    return std::move(t);
}

vector_of_finalized_Ts.push_back( some_function(std::move(some_T_ptr)));

or:

void some_function( T* t )
{
    // I don't own t and won't delete it if an exception happens
    // do stuff
}

some_function(some_T_ptr.get());
vector_of_finalized_Ts.push_back( std::move(some_T_ptr));

Either design is fine. It just depends on what code should own the pointer (especially if an exception is thrown at some point).

于 2011-05-07T19:21:46.837 回答
0

(Ignoring the unrelated syntax error in your code. See my comment above for that.)

As far as your snippet goes, your code is valid. The verbosity of the moves is the price you pay for using std::unique_ptr in this manner, and for passing the unique_ptr into the function rather than a reference to the object itself.

I suppose you have your good reasons for wanting some_function to take a std::unique_ptr and, if that's the case, then as far as I can tell you can't really do any better.

If you don't have your good reasons then, well, there's your answer. :)

Hope that helps.

于 2011-05-07T19:01:46.450 回答
0

Your problem is that you both take the unique_ptr by reference and return it. It's a unique pointer- you're treating it liked a shared pointer, and you're left with a wasted nullptr value on the stack. If you took it by value or by rvalue reference, you could just call some_function directly, and you don't have to move the result.

std::unique_ptr<T> some_function( std::unique_ptr<T> &&t )
{
    // do stuff
    return t;
}
vector_of_finalized_Ts.push_back( some_function(std::unique_ptr<T>(new T(...))));
于 2011-05-07T19:15:04.913 回答