Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::unique_ptr and pointer to pointer

I want to use std::unique_ptr in combination with FreeImage's FITAG. The code in plain C would be:

... load image;

FITAG* tag = NULL;
FreeImage_GetMetadata(FIMD_EXIF_EXIF, bitmap, "Property", &tag);
... do some stuff with tag;
FreeImage_DeleteTag(tag);

... delete image;

My attempt with unique_ptr:

std::unique_ptr<FITAG, void(*)(FITAG*)> tag(NULL, &FreeImage_DeleteTag);
FreeImage_GetMetadata(FIMD_EXIF_EXIF, bitmap, "Property", &tag.get());

which obviously returns:

cannot take the address of an rvalue of type 'pointer' (aka 'FITAG *')

How would I solve this?

Thanks a lot in advance.

like image 989
user2970139 Avatar asked Jul 03 '14 00:07

user2970139


2 Answers

Reverse the order of operations; first acquire the resource and then construct the unique_ptr.

FITAG *p = NULL;
FreeImage_GetMetadata(FIMD_EXIF_EXIF, bitmap, "Property", &p);
std::unique_ptr<FITAG, void(*)(FITAG*)> tag(p, &FreeImage_DeleteTag);
like image 61
Praetorian Avatar answered Oct 13 '22 01:10

Praetorian


tag.get()

This returns an r-value. You can't get the address of an r-value( temporary ). Your best bet is to do this instead:

auto ptr = tag.get();
FreeImage_GetMetadata(FIMD_EXIF_EXIF, bitmap, "Property", &ptr);

This will allow you to pass a FITAG** into the function. If you meant to pass a FITAG* into the function, just remove the & since tag.get() returns the pointer, not the value.

FreeImage_GetMetadata(FIMD_EXIF_EXIF, bitmap, "Property", tag.get());
like image 33
Ben Avatar answered Oct 13 '22 01:10

Ben