Skip to content

Instantly share code, notes, and snippets.

@janderudder
Last active March 14, 2020 12:32
Show Gist options
  • Save janderudder/13562bd1fd262e35635f4cb6559de53f to your computer and use it in GitHub Desktop.
Save janderudder/13562bd1fd262e35635f4cb6559de53f to your computer and use it in GitHub Desktop.
unique_ptr as parameter : difference between taking by value or by rvalue reference
#include <iostream>
#include <memory>
/**
* Sample types with loud destructors
*/
struct By_value
{
int i;
By_value(int ai) : i{ai} {};
~By_value() {
std::cout << "=> 'taken by value' (" << i << ") is now destructed\n";
}
};
struct By_rvalue_reference
{
int i;
By_rvalue_reference(int ai) : i{ai} {};
~By_rvalue_reference() {
std::cout << "=> 'taken by rvalue reference' (" << i << ") is now destructed\n";
}
};
/**
* Taking by rvalue ref enables us to steal the ownership or to leave the
* client's unique_ptr untouched.
*/
void get_value(std::unique_ptr<By_rvalue_reference>&& p, bool steal)
{
std::cout << "inside get_value(std::unique_ptr&&)\n";
if (steal) {
static auto stolen_ptr = std::move(p);
std::cout << "ownership has been stolen\n";
}
std::cout << "leaving the function\n";
}
/**
* Taking by value calls the move constructor immediately, which means the
* object is moved from client-site whatever happens in the functions.
* If we don't store it, it is destroyed at the end of function scope.
*/
void get_value(std::unique_ptr<By_value> p, bool steal)
{
std::cout << "inside get_value(std::unique_ptr)\n";
if (steal) {
static auto stolen_ptr = std::move(p);
std::cout << "ownership has been stolen\n";
}
std::cout << "leaving the function\n";
}
int main()
{
auto by_val_a = std::make_unique<By_value>(1);
auto by_val_b = std::make_unique<By_value>(2);
auto by_rval_ref_a = std::make_unique<By_rvalue_reference>(3);
auto by_rval_ref_b = std::make_unique<By_rvalue_reference>(4);
constexpr bool steal = true;
constexpr bool dont_steal = false;
get_value(std::move(by_val_a), steal); std::cout << "\n";
get_value(std::move(by_rval_ref_a), steal); std::cout << "\n";
get_value(std::move(by_val_b), dont_steal); std::cout << "\n";
get_value(std::move(by_rval_ref_b), dont_steal); std::cout << "\n";
std::cout << "leaving main\n\n";
}
/* Program output:
inside get_value(std::unique_ptr)
ownership has been stolen
leaving the function
inside get_value(std::unique_ptr&&)
ownership has been stolen
leaving the function
inside get_value(std::unique_ptr)
leaving the function
=> 'taken by value' (2) is now destructed
inside get_value(std::unique_ptr&&)
leaving the function
leaving main
=> 'taken by rvalue reference' (4) is now destructed
=> 'taken by rvalue reference' (3) is now destructed
=> 'taken by value' (1) is now destructed
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment