This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++14 status.

### 2176. Special members for `wstring_convert` and `wbuffer_convert`

Section: D.23.2 [depr.conversions.string], D.23.3 [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 for `wstring_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.

1. 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;

2. 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());

3. 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;

4. Edit the signature before [conversions.buffer] p10:

   >     explicit wbuffer_convert(std::streambuf *bytebuf = 0,
   >         Codecvt *pcvt = new Codecvt, state_type state = state_type());