je-woong.ku
je-woong.ku

Reputation: 91

Can std::unique_ptr be used as an argument?

Now, I'm just studying about smart_ptr (unique_ptr / shared_ptr). And I wrote test code like this for checking unique_ptr can be used as argument.

typedef struct __T_TEST
{
char cT1;
char cT2;
} T_TEST;

int main(...)
{
...
char szB[2] = {0x61, 0x62};

auto pTest = std::make_unique<T_TEST>();
std::memcpy(pTest, szB, 2);
printf("T1 = [%02x]\n", pTest->cT1);
printf("T2 = [%02x]\n", pTest->cT2);

return 0;
}

And then, I added one function using unique_ptr as parameter like this.

int TestPrint(std::unique_ptr<T_TEST> p_pData)
{
    printf("T1 in TestPrint Func = [%02x]\n", p_pData->cT1);
    printf("T2 in TestPrint Func = [%02x]\n", p_pData->cT2);
    return 0;
}

I'm just calling that function in main function after printf. But it doesn't work.

printf("T1 = [%02x]\n", pTest->cT1);
printf("T2 = [%02x]\n", pTest->cT2);

TestPrint(pTest);  <- Can't pass the pTest!

return 0;
}

In this case, I can't pass the pTest. Why not? I think pTest is std::unique_ptr and p_pData is std::unique_ptr in TestPrint function. So it's the same type!! But I can't. I want to know why it doesn't work.

Of course, it can work after changing the function to std::unique_ptr<T_TEST>& p_pData. But I don't understand why I can't pass the parameter despite of same data type.

Upvotes: 0

Views: 2311

Answers (1)

StereoMatching
StereoMatching

Reputation: 5019

std::unique_ptr is a move only type(cannot be copied), if you want to pass it in to the function as a parameter, you can

1 : pass by reference

int TestPrint(std::unique_ptr<T_TEST> const &p_pData)
{
    printf("T1 in TestPrint Func = [%02x]\n", p_pData->cT1);
    printf("T2 in TestPrint Func = [%02x]\n", p_pData->cT2);
    return 0;
}

2 : move it

TestPrint(std::move(pTest));

3 : do not use unique_ptr as parameter, use pointer

int TestPrint(T_TEST *p_pData)
{
    printf("T1 in TestPrint Func = [%02x]\n", p_pData->cT1);
    printf("T2 in TestPrint Func = [%02x]\n", p_pData->cT2);
    return 0;
}

TestPrint(pTest.get());

Pointer is bad at resource management, but good at access resource, if you do not need to pass the ownership to the function, you can use pointer to replace unique_ptr, this is more flexible IMHO, because the raw pointer can work with shared_ptr, unique_ptr, weal_ptr and other smart pointer, but unique_ptr must work with unique_ptr only.

In most cases, I only use smart pointer as a function parameter when I want to share(std::shared_ptr) or transfer ownership(std::unique_ptr).

Upvotes: 3

Related Questions