wstring_convert
and wbuffer_convert
Section: 99 [depr.conversions.string], 99 [depr.conversions.buffer] Status: C++14 Submitter: Jonathan Wakely Opened: 2012-08-02 Last modified: 2017-09-07
Priority: Not Prioritized
View other active issues in [depr.conversions.string].
View all other issues in [depr.conversions.string].
View all issues with C++14 status.
Discussion:
See discussion following c++std-lib-32699.
The constructors forwstring_convert
and wbuffer_convert
should be explicit, to avoid
implicit conversions which take ownership of a Codecvt
pointer and delete it unexpectedly.
Secondly, [conversions.buffer] p11 describes a destructor which is not declared in the class
synopsis in p2.
Finally, and most importantly, the definitions in [conversions.string] and
[conversions.buffer] imply implicitly-defined copy constructors and assignment operators, which
would do shallow copies of the owned Codecvt
objects and result in undefined behaviour in the
destructors.
Codecvt
is not required to be CopyConstructible
, so deep copies are not possible.
The wstring_convert
and wstring_buffer
types could be made move-only, but the proposed
resolution below doesn't do so because of the lack of preconditions regarding null Codecvt
pointers
and the absence of observer functions that would allow users to check preconditions (see also LWG 2175).
[2013-03-15 Issues Teleconference]
Moved to Review.
Jonathan pointed out that you can have an implicit constructor that takes ownership of a heap reference, which would result an unexpected deletion.
No-one really likes the 'naked new' in the interface here, either.
[2013-04-18, Bristol]
Proposed resolution:
This wording is relative to N3376.
Edit the class template wstring_convert
synopsis in [conversions.string] p2:
explicit wstring_convert(Codecvt *pcvt = new Codecvt); wstring_convert(Codecvt *pcvt, state_type state); explicit wstring_convert(const byte_string& byte_err, const wide_string& wide_err = wide_string()); ~wstring_convert(); wstring_convert(const wstring_convert&) = delete; wstring_convert& operator=(const wstring_convert&) = delete;
Edit the signatures before [conversions.string] p16:
explicit wstring_convert(Codecvt *pcvt = new Codecvt); wstring_convert(Codecvt *pcvt, state_type state); explicit wstring_convert(const byte_string& byte_err, const wide_string& wide_err = wide_string());
Edit the class template wbuffer_convert
synopsis in [conversions.buffer] p2:
explicit wbuffer_convert(std::streambuf *bytebuf = 0, Codecvt *pcvt = new Codecvt, state_type state = state_type()); ~wbuffer_convert(); wbuffer_convert(const wbuffer_convert&) = delete; wbuffer_convert& operator=(const wbuffer_convert&) = delete;
Edit the signature before [conversions.buffer] p10:
explicit wbuffer_convert(std::streambuf *bytebuf = 0, Codecvt *pcvt = new Codecvt, state_type state = state_type());