With shared_ptr you can use a custom deleter, like:
auto fp = shared_ptr<FILE>( fopen("file.txt", "rt"), &fclose );
fprintf( fp.get(), "hello\n" );
and this will remember to fclose
the file regardless of how the function exits.
However, it seems a bit overkill to refcount a local variable, so I want to use unique_ptr
:
auto fp = unique_ptr<FILE>( fopen("file.txt", "rt"), &fclose );
however, that does not compile.
Is this a defect? Is there a simple workaround? Im I missing something trivial?
Should be
unique_ptr<FILE, int(*)(FILE*)>(fopen("file.txt", "rt"), &fclose);
since http://en.cppreference.com/w/cpp/memory/unique_ptr
or, since you use C++11, you can use decltype
std::unique_ptr<FILE, decltype(&fclose)>
The above answer while its intent is OK and in practice compiles and works is wrong, because it is not specified that you are allowed to take the address of a standard library function. A C++ library implementation is allowed to provide different overloads or more parameters (with default arguments). Only calling the library function is sanctioned by the standard. Therefore, you need to wrap the call to fclose in your own function implementation or lambda, such as
unique_ptr<FILE, int(*)(FILE*)>(fopen("file.txt", "rt"),
[](FILE *fp)->int{ if(fp) ::fclose(fp);});
or wait for unique_resource
of https://wg21.link/p0052 to become standardized, but even there you need to use the lambda or a deleter function (object), see the more recent versions of p0052.
来源:https://stackoverflow.com/questions/26360916/using-custom-deleter-with-unique-ptr