开发者

function that modifies object pointed to by std::unique_ptr<T>

开发者 https://www.devze.com 2023-03-04 05:15 出处:网络
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:

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开发者_JAVA百科 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.


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).


(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.


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(...))));
0

精彩评论

暂无评论...
验证码 换一张
取 消