Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/string/basic string/insert"

From cppreference.com
< cpp‎ | string‎ | basic string
m (in iterator insert( iterator pos, std::initializer_list<CharT> ilist ); the first argument should not be const (gcc))
m (Synopsis: +constexpr since...)
 
(6 intermediate revisions by 4 users not shown)
Line 2: Line 2:
 
{{cpp/string/basic_string/navbar}}
 
{{cpp/string/basic_string/navbar}}
 
{{dcl begin}}
 
{{dcl begin}}
{{dcl rev multi|num=1
+
{{dcl|num=1|notes={{mark constexpr since c++20}}|
|dcl1=
+
 
basic_string& insert( size_type index, size_type count, CharT ch );
 
basic_string& insert( size_type index, size_type count, CharT ch );
|since2=c++20|dcl2=
 
constexpr basic_string& insert( size_type index, size_type count, CharT ch );
 
 
}}
 
}}
{{dcl rev multi|num=2
+
{{dcl|num=2|notes={{mark constexpr since c++20}}|
|dcl1=
+
 
basic_string& insert( size_type index, const CharT* s );
 
basic_string& insert( size_type index, const CharT* s );
|since2=c++20|dcl2=
 
constexpr basic_string& insert( size_type index, const CharT* s );
 
 
}}
 
}}
{{dcl rev multi|num=3
+
{{dcl|num=3|notes={{mark constexpr since c++20}}|
|dcl1=
+
 
basic_string& insert( size_type index, const CharT* s, size_type count );
 
basic_string& insert( size_type index, const CharT* s, size_type count );
|since2=c++20|dcl2=
 
constexpr basic_string& insert( size_type index,
 
                                const CharT* s, size_type count );
 
 
}}
 
}}
{{dcl rev multi|num=4
+
{{dcl|num=4|notes={{mark constexpr since c++20}}|
|dcl1=
+
 
basic_string& insert( size_type index, const basic_string& str );
 
basic_string& insert( size_type index, const basic_string& str );
|since2=c++20|dcl2=
 
constexpr basic_string& insert( size_type index, const basic_string& str );
 
 
}}
 
}}
 
{{dcl rev multi|num=5
 
{{dcl rev multi|num=5
 
|dcl1=
 
|dcl1=
 
basic_string& insert( size_type index, const basic_string& str,
 
basic_string& insert( size_type index, const basic_string& str,
                       size_type index_str, size_type count );
+
                       size_type s_index, size_type count );
|since2=c++14|dcl2=
+
|since2=c++14|notes2={{mark constexpr since c++20}}|dcl2=
 
basic_string& insert( size_type index, const basic_string& str,
 
basic_string& insert( size_type index, const basic_string& str,
                       size_type index_str, size_type count = npos );
+
                       size_type s_index, size_type count = npos );
|since3=c++20|dcl3=
+
constexpr basic_string& insert( size_type index, const basic_string& str,
+
                                size_type index_str, size_type count = npos );
+
 
}}
 
}}
 
{{dcl rev multi|num=6
 
{{dcl rev multi|num=6
 
|dcl1=
 
|dcl1=
 
iterator insert( iterator pos, CharT ch );
 
iterator insert( iterator pos, CharT ch );
|since2=c++11|dcl2=
+
|since2=c++11|notes2={{mark constexpr since c++20}}|dcl2=
 
iterator insert( const_iterator pos, CharT ch );
 
iterator insert( const_iterator pos, CharT ch );
|since3=c++20|dcl3=
 
constexpr iterator insert( const_iterator pos, CharT ch );
 
 
}}
 
}}
 
{{dcl rev multi|num=7
 
{{dcl rev multi|num=7
 
|dcl1=
 
|dcl1=
 
void insert( iterator pos, size_type count, CharT ch );
 
void insert( iterator pos, size_type count, CharT ch );
|since2=c++11|dcl2=
+
|since2=c++11|notes2={{mark constexpr since c++20}}|dcl2=
 
iterator insert( const_iterator pos, size_type count, CharT ch );
 
iterator insert( const_iterator pos, size_type count, CharT ch );
|since3=c++20|dcl3=
 
constexpr iterator insert( const_iterator pos, size_type count, CharT ch );
 
 
}}
 
}}
 
{{dcl rev multi|num=8
 
{{dcl rev multi|num=8
Line 58: Line 38:
 
template< class InputIt >
 
template< class InputIt >
 
void insert( iterator pos, InputIt first, InputIt last );
 
void insert( iterator pos, InputIt first, InputIt last );
|since2=c++11|dcl2=
+
|since2=c++11|notes2={{mark constexpr since c++20}}|dcl2=
 
template< class InputIt >
 
template< class InputIt >
 
iterator insert( const_iterator pos, InputIt first, InputIt last );
 
iterator insert( const_iterator pos, InputIt first, InputIt last );
|since3=c++20|dcl3=
 
template< class InputIt >
 
constexpr iterator insert( const_iterator pos, InputIt first, InputIt last );
 
 
}}
 
}}
{{dcl rev multi|num=9
+
{{dcl|num=9|since=c++11|notes={{mark constexpr since c++20}}|
|since1=c++11|dcl1=
+
iterator insert( const_iterator pos, std::initializer_list<CharT> ilist );
iterator insert( iterator pos, std::initializer_list<CharT> ilist );
+
|since2=c++20|dcl2=
+
constexpr iterator insert( const_iterator pos,
+
                          std::initializer_list<CharT> ilist );
+
 
}}
 
}}
{{dcl rev multi|num=10
+
{{dcl|num=10|since=c++17|notes={{mark constexpr since c++20}}|
|since1=c++17|dcl1=
+
 
template< class StringViewLike >
 
template< class StringViewLike >
basic_string& insert( size_type pos, const StringViewLike& t );
+
basic_string& insert( size_type index, const StringViewLike& t );
|since2=c++20|dcl2=
+
template< class StringViewLike >
+
constexpr basic_string& insert( size_type pos, const StringViewLike& t );
+
 
}}
 
}}
{{dcl rev multi|num=11
+
{{dcl|num=11|since=c++17|notes={{mark constexpr since c++20}}|1=
|since1=c++17|dcl1=
+
 
template< class StringViewLike >
 
template< class StringViewLike >
 
basic_string& insert( size_type index, const StringViewLike& t,
 
basic_string& insert( size_type index, const StringViewLike& t,
                       size_type index_str, size_type count = npos );
+
                       size_type t_index, size_type count = npos );
|since2=c++20|dcl2=
+
template< class StringViewLike >
+
constexpr basic_string& insert( size_type index, const StringViewLike& t,
+
                                size_type index_str, size_type count = npos );
+
 
}}
 
}}
 
{{dcl end}}
 
{{dcl end}}
Line 94: Line 58:
 
Inserts characters into the string.
 
Inserts characters into the string.
  
@1@ Inserts {{tt|count}} copies of character {{tt|ch}} at the position {{tt|index}}
+
@1@ Inserts {{c|count}} copies of character {{c|ch}} at the position {{c|index}}.
  
@2@ Inserts null-terminated character string pointed to by {{tt|s}} at the position {{tt|index}}. The length of the string is determined by the first null character using {{c|Traits::length(s)}}.  
+
@2@ Inserts null-terminated character string pointed to by {{c|s}} at the position {{c|index}}. The length of the string is determined by the first null character using {{c|Traits::length(s)}}.  
  
@3@ Inserts the characters in the range {{tt|[s, s+count)}} at the position {{tt|index}}. The range can contain null characters.
+
@3@ Inserts the characters in the range {{range|s|s + count}} at the position {{c|index}}. The range can contain null characters.
  
@4@ Inserts string {{tt|str}} at the position {{tt|index}}
+
@4@ Inserts string {{c|str}} at the position {{c|index}}.
  
@5@ Inserts a string, obtained by {{c|str.substr(index_str, count)}} at the position {{tt|index}}
+
@5@ Inserts a string, obtained by {{c|str.substr(s_index, count)}} at the position {{c|index}}.
  
@6@ Inserts character {{tt|ch}} before the character pointed by {{tt|pos}}
+
@6@ Inserts character {{c|ch}} before the character pointed by {{c|pos}}.
  
@7@ Inserts {{tt|count}} copies of character {{tt|ch}} before the element (if any) pointed by {{tt|pos}}
+
@7@ Inserts {{c|count}} copies of character {{c|ch}} before the element (if any) pointed by {{c|pos}}.
  
@8@ Inserts characters from the range {{tt|[first, last)}} before the element (if any) pointed by {{tt|pos}}. {{rev inl|since=c++11|This overload does not participate in overload resolution if {{tt|InputIt}} does not satisfy {{named req|InputIterator}}.}}
+
@8@ Inserts characters from the range {{range|first|last}} before the element (if any) pointed by {{c|pos}}, as if by {{c|insert(pos - begin(), basic_string(first, last, get_allocator()))}}.
 +
{{rrev|since=c++11|
 +
This overload does not participate in overload resolution if {{tt|InputIt}} does not satisfy {{named req|InputIterator}}.
 +
}}
 +
 
 +
@9@ Inserts elements from initializer list {{c|ilist}} before the element (if any) pointed by {{c|pos}}.
  
@9@ Inserts elements from initializer list {{tt|ilist}} before the element (if any) pointed by {{tt|pos}}
+
@10@ {{cpp/string/sv hack|inserts the elements from {{c|sv}} before the element (if any) pointed by {{c|index}}, as if by {{c|insert(index, sv.data(), sv.size())}}}}
  
@10@ {{cpp/string/sv hack|inserts the elements from {{tt|sv}} before the element (if any) pointed by {{tt|pos}}, as if by {{c|insert(pos, sv.data(), sv.size())}}}}
+
@11@ {{cpp/string/sv hack|inserts, before the element (if any) pointed by {{c|index}}, the characters from the subview {{range|t_index|t_index + count}} of {{c|sv}}.
 +
* If the requested subview lasts past the end of {{c|sv}}, or if {{c|1=count == npos}}, the resulting subview is {{range|t_index|sv.size()}}.
 +
* If {{c|t_index > sv.size()}}, or if {{c|index > size()}}, {{lc|std::out_of_range}} is thrown}}
  
@11@ {{cpp/string/sv hack|inserts, before the element (if any) pointed by {{tt|pos}}, the characters from the subview {{tt|[index_str, index_str+count)}} of {{tt|sv}}. If the requested subview lasts past the end of {{tt|sv}}, or if {{c|1=count == npos}}, the resulting subview is {{tt|[index_str, sv.size())}}. If {{c|1=index_str > sv.size()}}, or if {{c|index > size()}}, {{lc|std::out_of_range}} is thrown}}
+
If {{c|pos}} is not a valid iterator on {{c|*this}}, the behavior is undefined.  
  
 
===Parameters===
 
===Parameters===
Line 125: Line 96:
 
{{par|str|string to insert}}
 
{{par|str|string to insert}}
 
{{par|first, last|range defining characters to insert}}
 
{{par|first, last|range defining characters to insert}}
{{par|index_str|position of the first character in the string {{tt|str}} to insert}}
+
{{par|s_index|position of the first character in {{c|str}} to insert}}
 
{{par|ilist|{{lc|std::initializer_list}} to insert the characters from}}
 
{{par|ilist|{{lc|std::initializer_list}} to insert the characters from}}
 
{{par|t|object (convertible to {{lc|std::basic_string_view}}) to insert the characters from}}
 
{{par|t|object (convertible to {{lc|std::basic_string_view}}) to insert the characters from}}
 +
{{par|t_index|position of the first character in {{c|t}} to insert}}
 
{{par hreq}}
 
{{par hreq}}
 
{{par req named|InputIt|InputIterator}}
 
{{par req named|InputIt|InputIterator}}
Line 133: Line 105:
  
 
===Return value===
 
===Return value===
@1-5,10-11@ {{c|*this}}
+
@1-5@ {{c|*this}}
  
@6-9@ An iterator which refers to the copy of the first inserted character or {{tt|pos}} if no characters were inserted ({{c|count{{==}}0}} or {{c|first{{==}}last}} or {{c|ilist.size(){{==}}0}})
+
@6-9@ An iterator which refers to the copy of the first inserted character or {{c|pos}} if no characters were inserted ({{c|1=count == 0}} or {{c|1=first == last}} or {{c|1=ilist.size() == 0}})
 +
 
 +
@10,11@ {{c|*this}}
  
 
===Exceptions===
 
===Exceptions===
@1-4, 10@ Throws {{lc|std::out_of_range}} if {{c|index > size()}}.
+
@1-4,10@ Throws {{lc|std::out_of_range}} if {{c|index > size()}}.
@5@ Throws {{lc|std::out_of_range}} if {{c|index > size()}} or if {{c|index_str > str.size()}}.
+
@5@ Throws {{lc|std::out_of_range}} if {{c|index > size()}} or if {{c|s_index > str.size()}}.
@11@ Throws {{lc|std::out_of_range}} if {{c|index > size()}} or if {{c|index_str > sv.size()}}.
+
@11@ Throws {{lc|std::out_of_range}} if {{c|index > size()}} or if {{c|t_index > sv.size()}}.
  
In all cases, throws {{lc|std::length_error}} if {{c|size() + ins_count > max_size()}} where {{tt|ins_count}} is the number of characters that will be inserted and may throw any exceptions thrown by {{tt|Allocator::allocate}}.
+
In all cases, throws {{lc|std::length_error}} if {{c|size() + ins_count > max_size()}} where {{c|ins_count}} is the number of characters that will be inserted.
  
{{rrev|since=c++11|
+
{{rrev|since=c++20|
In any case, if an exception is thrown for any reason, this function has no effect (strong exception guarantee).
+
In all cases, if {{c/core|std::allocator_traits<Allocator>::allocate}} throws an exception, it is rethrown.
 
}}
 
}}
 +
 +
{{cpp/strong exception safety guarantee}}
  
 
===Example===
 
===Example===
{{example|code=
+
{{example
 +
|code=
 
#include <cassert>
 
#include <cassert>
 
#include <iterator>
 
#include <iterator>
Line 159: Line 136:
 
{
 
{
 
     std::string s = "xmplr";
 
     std::string s = "xmplr";
 
+
   
 
     // insert(size_type index, size_type count, char ch)
 
     // insert(size_type index, size_type count, char ch)
 
     s.insert(0, 1, 'E');
 
     s.insert(0, 1, 'E');
 
     assert("Exmplr" == s);
 
     assert("Exmplr" == s);
 
+
   
 
     // insert(size_type index, const char* s)
 
     // insert(size_type index, const char* s)
 
     s.insert(2, "e");
 
     s.insert(2, "e");
 
     assert("Exemplr" == s);
 
     assert("Exemplr" == s);
 
+
   
 
     // insert(size_type index, string const& str)
 
     // insert(size_type index, string const& str)
 
     s.insert(6, "a"s);
 
     s.insert(6, "a"s);
 
     assert("Exemplar" == s);
 
     assert("Exemplar" == s);
 
+
   
 
     // insert(size_type index, string const& str,
 
     // insert(size_type index, string const& str,
     //        size_type index_str, size_type count)
+
     //        size_type s_index, size_type count)
 
     s.insert(8, " is an example string."s, 0, 14);
 
     s.insert(8, " is an example string."s, 0, 14);
 
     assert("Exemplar is an example" == s);
 
     assert("Exemplar is an example" == s);
 
+
   
 
     // insert(const_iterator pos, char ch)
 
     // insert(const_iterator pos, char ch)
 
     s.insert(s.cbegin() + s.find_first_of('n') + 1, ':');
 
     s.insert(s.cbegin() + s.find_first_of('n') + 1, ':');
 
     assert("Exemplar is an: example" == s);
 
     assert("Exemplar is an: example" == s);
 
+
   
 
     // insert(const_iterator pos, size_type count, char ch)
 
     // insert(const_iterator pos, size_type count, char ch)
 
     s.insert(s.cbegin() + s.find_first_of(':') + 1, 2, '=');
 
     s.insert(s.cbegin() + s.find_first_of(':') + 1, 2, '=');
 
     assert("Exemplar is an:== example" == s);
 
     assert("Exemplar is an:== example" == s);
 
+
   
 
     // insert(const_iterator pos, InputIt first, InputIt last)
 
     // insert(const_iterator pos, InputIt first, InputIt last)
 
     {
 
     {
Line 192: Line 169:
 
         assert("Exemplar is an:== example string" == s);
 
         assert("Exemplar is an:== example string" == s);
 
     }
 
     }
 
+
   
 
     // insert(const_iterator pos, std::initializer_list<char>)
 
     // insert(const_iterator pos, std::initializer_list<char>)
     s.insert(s.cbegin() + s.find_first_of('g') + 1, { '.' });
+
     s.insert(s.cbegin() + s.find_first_of('g') + 1, {'.'});
 
     assert("Exemplar is an:== example string." == s);
 
     assert("Exemplar is an:== example string." == s);
 
}
 
}
Line 202: Line 179:
 
===Defect reports===
 
===Defect reports===
 
{{dr list begin}}
 
{{dr list begin}}
{{dr list item|wg=lwg|dr=7|std=C++98|before=the effect of overload {{v|8}} referred to a non-existing overload|after=refers to overload {{v|4}} correctly}}
+
{{dr list item|wg=lwg|dr=7|std=C++98|before=overload {{v|8}} referred to a non-existing overload|after=refers to overload {{v|4}} correctly}}
{{dr list item|wg=lwg|dr=2946|std=C++17|before={{tt|string_view}} overload causes ambiguity in some cases|after=avoided by making it a template}}
+
{{dr list item|wg=lwg|dr=847|std=C++98|before=there was no exception safety guarantee|after=added strong exception safety guarantee}}
 +
{{dr list item|wg=lwg|dr=2946|std=C++17|before=overload {{v|10}} caused ambiguity in some cases|after=avoided by making it a template}}
 
{{dr list end}}
 
{{dr list end}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
 +
{{dsc inc|cpp/string/basic_string/dsc insert_range}}
 
{{dsc inc|cpp/string/basic_string/dsc append}}
 
{{dsc inc|cpp/string/basic_string/dsc append}}
 
{{dsc inc|cpp/string/basic_string/dsc push_back}}
 
{{dsc inc|cpp/string/basic_string/dsc push_back}}

Latest revision as of 06:23, 22 April 2024

 
 
 
std::basic_string
Member functions
Element access
Iterators
Capacity
Modifiers
basic_string::insert
Search
Operations
Constants
Non-member functions
I/O
Comparison
(until C++20)(until C++20)(until C++20)(until C++20)(until C++20)(C++20)
Numeric conversions
(C++11)(C++11)(C++11)
(C++11)(C++11)
(C++11)(C++11)(C++11)
(C++11)
(C++11)
Literals
Helper classes
Deduction guides (C++17)

 
basic_string& insert( size_type index, size_type count, CharT ch );
(1) (constexpr since C++20)
basic_string& insert( size_type index, const CharT* s );
(2) (constexpr since C++20)
basic_string& insert( size_type index, const CharT* s, size_type count );
(3) (constexpr since C++20)
basic_string& insert( size_type index, const basic_string& str );
(4) (constexpr since C++20)
(5)
basic_string& insert( size_type index, const basic_string& str,
                      size_type s_index, size_type count );
(until C++14)
basic_string& insert( size_type index, const basic_string& str,
                      size_type s_index, size_type count = npos );
(since C++14)
(constexpr since C++20)
(6)
iterator insert( iterator pos, CharT ch );
(until C++11)
iterator insert( const_iterator pos, CharT ch );
(since C++11)
(constexpr since C++20)
(7)
void insert( iterator pos, size_type count, CharT ch );
(until C++11)
iterator insert( const_iterator pos, size_type count, CharT ch );
(since C++11)
(constexpr since C++20)
(8)
template< class InputIt >
void insert( iterator pos, InputIt first, InputIt last );
(until C++11)
template< class InputIt >
iterator insert( const_iterator pos, InputIt first, InputIt last );
(since C++11)
(constexpr since C++20)
iterator insert( const_iterator pos, std::initializer_list<CharT> ilist );
(9) (since C++11)
(constexpr since C++20)
template< class StringViewLike >
basic_string& insert( size_type index, const StringViewLike& t );
(10) (since C++17)
(constexpr since C++20)
template< class StringViewLike >

basic_string& insert( size_type index, const StringViewLike& t,

                      size_type t_index, size_type count = npos );
(11) (since C++17)
(constexpr since C++20)

Inserts characters into the string.

1) Inserts count copies of character ch at the position index.
2) Inserts null-terminated character string pointed to by s at the position index. The length of the string is determined by the first null character using Traits::length(s).
3) Inserts the characters in the range [ss + count) at the position index. The range can contain null characters.
4) Inserts string str at the position index.
5) Inserts a string, obtained by str.substr(s_index, count) at the position index.
6) Inserts character ch before the character pointed by pos.
7) Inserts count copies of character ch before the element (if any) pointed by pos.
8) Inserts characters from the range [firstlast) before the element (if any) pointed by pos, as if by insert(pos - begin(), basic_string(first, last, get_allocator())).

This overload does not participate in overload resolution if InputIt does not satisfy LegacyInputIterator.

(since C++11)
9) Inserts elements from initializer list ilist before the element (if any) pointed by pos.
10) Implicitly converts t to a string view sv as if by std::basic_string_view<CharT, Traits> sv = t;, then inserts the elements from sv before the element (if any) pointed by index, as if by insert(index, sv.data(), sv.size()).
This overload participates in overload resolution only if std::is_convertible_v<const StringViewLike&,
                      std::basic_string_view<CharT, Traits>>
is true and std::is_convertible_v<const StringViewLike&, const CharT*> is false.
11) Implicitly converts t to a string view sv as if by std::basic_string_view<CharT, Traits> sv = t;, then inserts, before the element (if any) pointed by index, the characters from the subview [t_indext_index + count) of sv.
  • If the requested subview lasts past the end of sv, or if count == npos, the resulting subview is [t_indexsv.size()).
  • If t_index > sv.size(), or if index > size(), std::out_of_range is thrown.
This overload participates in overload resolution only if std::is_convertible_v<const StringViewLike&,
                      std::basic_string_view<CharT, Traits>>
is true and std::is_convertible_v<const StringViewLike&, const CharT*> is false.

If pos is not a valid iterator on *this, the behavior is undefined.

Contents

[edit] Parameters

index - position at which the content will be inserted
pos - iterator before which the characters will be inserted
ch - character to insert
count - number of characters to insert
s - pointer to the character string to insert
str - string to insert
first, last - range defining characters to insert
s_index - position of the first character in str to insert
ilist - std::initializer_list to insert the characters from
t - object (convertible to std::basic_string_view) to insert the characters from
t_index - position of the first character in t to insert
Type requirements
-
InputIt must meet the requirements of LegacyInputIterator.

[edit] Return value

1-5) *this
6-9) An iterator which refers to the copy of the first inserted character or pos if no characters were inserted (count == 0 or first == last or ilist.size() == 0)
10,11) *this

[edit] Exceptions

1-4,10) Throws std::out_of_range if index > size().
5) Throws std::out_of_range if index > size() or if s_index > str.size().
11) Throws std::out_of_range if index > size() or if t_index > sv.size().

In all cases, throws std::length_error if size() + ins_count > max_size() where ins_count is the number of characters that will be inserted.

In all cases, if std::allocator_traits<Allocator>::allocate throws an exception, it is rethrown.

(since C++20)

If an exception is thrown for any reason, this function has no effect (strong exception safety guarantee).

[edit] Example

#include <cassert>
#include <iterator>
#include <string>
 
using namespace std::string_literals;
 
int main()
{
    std::string s = "xmplr";
 
    // insert(size_type index, size_type count, char ch)
    s.insert(0, 1, 'E');
    assert("Exmplr" == s);
 
    // insert(size_type index, const char* s)
    s.insert(2, "e");
    assert("Exemplr" == s);
 
    // insert(size_type index, string const& str)
    s.insert(6, "a"s);
    assert("Exemplar" == s);
 
    // insert(size_type index, string const& str,
    //        size_type s_index, size_type count)
    s.insert(8, " is an example string."s, 0, 14);
    assert("Exemplar is an example" == s);
 
    // insert(const_iterator pos, char ch)
    s.insert(s.cbegin() + s.find_first_of('n') + 1, ':');
    assert("Exemplar is an: example" == s);
 
    // insert(const_iterator pos, size_type count, char ch)
    s.insert(s.cbegin() + s.find_first_of(':') + 1, 2, '=');
    assert("Exemplar is an:== example" == s);
 
    // insert(const_iterator pos, InputIt first, InputIt last)
    {
        std::string seq = " string";
        s.insert(s.begin() + s.find_last_of('e') + 1,
            std::begin(seq), std::end(seq));
        assert("Exemplar is an:== example string" == s);
    }
 
    // insert(const_iterator pos, std::initializer_list<char>)
    s.insert(s.cbegin() + s.find_first_of('g') + 1, {'.'});
    assert("Exemplar is an:== example string." == s);
}

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 7 C++98 overload (8) referred to a non-existing overload refers to overload (4) correctly
LWG 847 C++98 there was no exception safety guarantee added strong exception safety guarantee
LWG 2946 C++17 overload (10) caused ambiguity in some cases avoided by making it a template

[edit] See also

inserts a range of characters
(public member function) [edit]
appends characters to the end
(public member function) [edit]
appends a character to the end
(public member function) [edit]