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: 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 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(i)).

[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:

     wstring_convert(Codecvt *pcvt = new Codecvt);
    wstring_convert(Codecvt *pcvt, state_type state);
     wstring_convert(const byte_string& byte_err,
                             const wide_string& wide_err = wide_string());
    ~wstring_convert();
    				 
    
  2. Edit the signatures before [conversions.string] p16:

     wstring_convert(Codecvt *pcvt = new Codecvt);
    wstring_convert(Codecvt *pcvt, state_type state);
     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:

     wbuffer_convert(std::streambuf *bytebuf = 0,
                             Codecvt *pcvt = new Codecvt,
                             state_type state = state_type());
    						 
    
  4. Edit the signature before [conversions.buffer] p10:

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