Doc No:   X3J16/95-0094
							  WG21/N0694
						Date:     11 May 1995
						Project:  Programming Language C++
						Reply to: Jason Merrill
						          Cygnus Support
						          1937 Landings Dr
						          Mtn View, CA  94043 USA
						          jason@cygnus.com

Single-character operations for basic_string

Introduction

This proposal seeks to improve the usability of the basic_string template. It proposes removing from some method signatures default arguments that do not provide any additional expressive power and adding other methods for greater consistency within the basic_string class.

Discussion

For the sake of consistency with the standard sequences, the signatures of the basic_string members which operate on single characters were changed to put the size parameter before the character parameter. For instance,
  basic_string& append(charT c, size_t rep = 1);
became
  basic_string& append(size_type n, charT c = charT());
This change broke consistency with the similar methods for dealing with other basic_strings and character pointers; the syntax for appending a string, a character pointer and a single character are
  s.append(s2);
  s.append("Hi mom");
  s.append(1,'c');  // inconsistent
Furthermore, because of the default arguments, code which assumes that the methods are consistent and writes
  s.append('c');
silently does the wrong thing, appending 99 null characters rather than appending a single `c' or even requiring a diagnostic. I believe that consistency within the class and ease of use are more important than consistency with features of the standard STL sequences which are not part of the sequence requirements.

Proposals

  1. Remove the default arguments from all parameters of type charT. Specifically, change the signatures
      basic_string& append(size_type n, charT c = charT());
      basic_string& assign(size_type n, charT c = charT());
      basic_string& insert(size_type pos, size_type n, charT c = charT() );
      iterator insert(iterator p, charT c = charT());
      iterator insert(iterator p, size_type n, charT c = charT());
      basic_string& replace(size_type pos, size_type n, charT c = charT());
      basic_string& replace(iterator i1, iterator i2,size_type n, charT c = charT());
    
    to
      basic_string& append(size_type n, charT c);
      basic_string& assign(size_type n, charT c);
      basic_string& insert(size_type pos, size_type n, charT c);
      iterator insert(iterator p, charT c);
      iterator insert(iterator p, size_type n, charT);
      basic_string& replace(size_type pos, size_type n, charT);
      basic_string& replace(iterator i1, iterator i2,size_type n, charT c);
    
    This item will prevent confusing mistakes like the one above by making them ill-formed.

    The only possible drawback to this item is that generic code expecting the default arguments to the iterator insert methods which are provided by other sequences will fail to compile. This is not a major drawback, as the default arguments are not required by the sequence requirements, so the code would not be STL-conformant in any case.

  2. Add corresponding methods to operate on single characters, specifically
      basic_string(charT c, Allocator& = Allocator());
      basic_string& append(charT c)
        // { return append (1, c); }
      basic_string& assign(charT c)
        // { return assign (1, c); }
      basic_string& insert(size_type pos, charT c)
        // { return insert (pos, 1, c); }
      // iterator insert(iterator p, charT c) already provided
      basic_string& replace(size_type pos, charT c)
        // { return replace (pos, 1, c); }
      basic_string& replace(iterator i1, iterator i2, charT c)
        // { return replace (i1, i2, 1, c); }
    
    This item will make the interfaces for dealing with strings, character pointers and single characters consistent again, and make the other mutation functions consistent with insert -- the single-character variant of insert is part of the sequence requirements.

    A possible drawback to this item is that code trying to, say, append a number of nulls without explicitly specifying the null character will silently append a single character instead. I believe that the number of programmers that will actually want to append a group of nulls and would rely on the default argument to do so is very close to 0.

  3. Add another replace method to allow the number of characters added to be specified separately from the number of characters removed,
      basic_string& replace(size_type pos, size_type n1, size_type n2, charT c);
         // { return replace (pos, n1, basic_string (n2, c)); }
    
    and change the semantics of
      basic_string& replace(size_type pos, size_type n, charT c);
    
    to be
        { return replace (pos, n, basic_string(1, c)); }
    
    rather than
        { return replace (pos, n, basic_string(n, c)); }
    
    This item will improve the consistency of the character replace methods with the other methods in the class.