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

### 167. Improper use of `traits_type::length()`

Section: 31.7.6.3.4 [ostream.inserters.character] Status: CD1 Submitter: Dietmar Kühl Opened: 1999-07-20 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [ostream.inserters.character].

View all issues with CD1 status.

Discussion:

Paragraph 4 states that the length is determined using `traits::length(s)`. Unfortunately, this function is not defined for example if the character type is `wchar_t` and the type of `s` is `char const*`. Similar problems exist if the character type is `char` and the type of `s` is either `signed char const*` or `unsigned char const*`.

Proposed resolution:

Change 31.7.6.3.4 [ostream.inserters.character] paragraph 4 from:

> Effects: Behaves like an formatted inserter (as described in lib.ostream.formatted.reqmts) of out. After a sentry object is constructed it inserts characters. The number of characters starting at s to be inserted is traits::length(s). Padding is determined as described in lib.facet.num.put.virtuals. The traits::length(s) characters starting at s are widened using out.widen (lib.basic.ios.members). The widened characters and any required padding are inserted into out. Calls width(0).

to:

> Effects: Behaves like a formatted inserter (as described in lib.ostream.formatted.reqmts) of out. After a sentry object is constructed it inserts n characters starting at s, where n is the number that would be computed as if by:

> - traits::length(s) for the overload where the first argument is of type basic_ostream<charT, traits>& and the second is of type const charT*, and also for the overload where the first argument is of type basic_ostream<char, traits>& and the second is of type const char*.
> - std::char_traits<char>::length(s) for the overload where the first argument is of type basic_ostream<charT, traits>& and the second is of type const char*.
> - traits::length(reinterpret_cast<const char*>(s)) for the other two overloads.

> Padding is determined as described in lib.facet.num.put.virtuals. The n characters starting at s are widened using out.widen (lib.basic.ios.members). The widened characters and any required padding are inserted into out. Calls width(0).

[Santa Cruz: Matt supplied new wording]

[Kona: changed "where n is" to " where n is the number that would be computed as if by"]

Rationale:

We have five separate cases. In two of them we can use the user-supplied traits class without any fuss. In the other three we try to use something as close to that user-supplied class as possible. In two cases we've got a traits class that's appropriate for char and what we've got is a const signed char* or a const unsigned char*; that's close enough so we can just use a reinterpret cast, and continue to use the user-supplied traits class. Finally, there's one case where we just have to give up: where we've got a traits class for some arbitrary charT type, and we somehow have to deal with a const char*. There's nothing better to do but fall back to char_traits<char>