In this proposal:
N3830 Scoped Resource - Generic RAII Wrapper for the Standard Library
a scoped_resource
RAII wrapper is presented.
On page 4, there is some code like this:
auto hFile = std::make_scoped_resource(
...
);
...
// cast operator makes it seamless to use with other APIs needing a HANDLE
ReadFile(hFile, ...);
The Win32 API ReadFile()
takes a raw HANDLE
parameter, instead hFile
is an instance of scoped_resource
, so to make the above code work, there is an implicit cast operator implemented by scoped_resource
.
But, wasn't the "modern" recommendation to avoid these kind of implicit conversions?
For example, ATL/MFC CString
has an implicit conversion (cast operator) to LPCTSTR
(const char/wchar_t*
, i.e. a raw C-string pointer), instead STL strings have an explicit c_str()
method.
Similarly, smart pointers like unique_ptr
have an explicit get()
method to access the underlying wrapped pointer; and that recommendation against implicit conversion seems also present in this blog post:
Reader Q&A: Why don’t modern smart pointers implicitly convert to *?
So, are these implicit conversions (like ATL/MFC CString
and the newly proposed scoped_resource
) good or not for modern C++?
From a coding perspective, I'd say that being able to simply directly pass a RAII wrapper - be it CString
or scoped_resource
- to a C API expecting a "raw" parameter (like a raw C string pointer, or raw handle), relying on implicit conversions, and without calling some .GetString()
/.get()
method, seems very convenient.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…