Originally Posted by
Inanna
Yes, but why is the lambda signature's FILE* compatible with the function template's FILE*& when using a function instead of a function template is not? That was my question. It should fail to compile if the signatures do not match, but two C++0x compilers compile it without any warnings or errors.
I assume that is, because as Soma says, std::function does some work "behind the scenes".
I don't know more than that.
The are two problems that brought me to my own RAII wrapper:
- A direct lambda can not be used in place of fclose_deleter
Code:
// Will not compile!
unique_ptr<FILE, [](FILE* fp) { if (fp) fclose(fp); }> in(fopen("test.txt", "r"));
Of course not, as unique_ptr wants the type, not the object
However, it is possible to do something like:
Code:
auto closer = [](FILE* fp) { if (fp) fclose(fp); };
unique_ptr<FILE,decltype(closer)> in(fopen("test.txt", "r"), closer);
Or you can even abstract that with your own function:
Code:
template<typename ptr_t, closer_t> std::unique_ptr<ptr_t, closer_t> make_unique_ptr(ptr_t ptr, closer_t closer)
{
return std::unique_ptr<ptr_t, closer_t>(ptr, closer);
}
auto ptr = make_unique_ptr(fopen("test.txt", "r"), [](FILE* f) { if (f) fclose(f); });
[*]To get the FILE* from a unique_ptr, I needed to call get(). I wanted the RAII wrapper to sit in place of the unmanaged resource without any extra syntax to use it.[/list]
That's not a good idea unless you use a compiler that supports explicit conversion operators.
Boost::ScopeExit did not even enter the running because it is ugly as sin.
It's not that ugly.
Besides, it is handy for the times when you want to do cleanup before exiting the scope without having to write a RAII wrapper for it.