【初心者向け】C++の「std::basic_string::append」でできることとは?基本から応用まで徹底解説


std::basic_string::append は、以下の 7 つのオーバーロードを持つテンプレート関数です。

  1. append(const std::basic_string& str)
    str の内容を末尾にコピーして追加します。
  2. append(const std::basic_string_view& str)
    str の内容を末尾にコピーして追加します。
  3. append(const char* s)
    s で始まる C 文字列の内容を末尾にコピーして追加します。
  4. append(const char* s, std::size_t n)
    s で始まる C 文字列の先頭から n 文字を末尾にコピーして追加します。
  5. append(char ch)
    ch を末尾に 1 回追加します。
  6. append(std::initializer_list<char> il)
    il の内容を末尾にコピーして追加します。
  7. append(const std::basic_string& str, std::size_t pos, std::size_t n)
    strpos 番目の文字から n 文字を末尾にコピーして追加します。

これらのオーバーロードは、さまざまな種類の文字列データの追加を可能にし、状況に応じて柔軟な使い分けができます。

以下の例は、std::basic_string::append の使用方法を示しています。

#include <string>

int main() {
  std::string str1 = "Hello";
  std::string str2 = "World";

  // str1 に str2 を連結
  str1.append(str2);
  std::cout << str1 << std::endl; // 出力: HelloWorld

  // str1 に C 文字列を連結
  str1.append("!");
  std::cout << str1 << std::endl; // 出力: HelloWorld!

  // str1 に単一文字を連結
  str1.append('?');
  std::cout << str1 << std::endl; // 出力: HelloWorld!?

  return 0;
}

この例では、str1str2、C 文字列 "!", 単一文字 '?' をそれぞれ連結しています。

  • C++11 以降では、std::basic_string_view を使用することで、パフォーマンスを向上させることができます。
  • 連結する文字列の長さを事前に把握しておくことが望ましいです。そうでない場合、メモリ再割り当てが発生し、パフォーマンスが低下する可能性があります。
  • std::basic_string::append は、既存の文字列オブジェクトを変更するメソッドです。別の文字列オブジェクトを作成する場合は、std::operator+std::string::assign などの他の方法を使用する必要があります。


例 1: 文字列オブジェクトの連結

#include <string>

int main() {
  std::string str1 = "Hello";
  std::string str2 = "World";

  // str1 に str2 を連結
  str1.append(str2);
  std::cout << str1 << std::endl; // 出力: HelloWorld

  return 0;
}

例 2: C 文字列の連結

#include <string>

int main() {
  std::string str1 = "Hello";

  // str1 に C 文字列を連結
  str1.append("!");
  std::cout << str1 << std::endl; // 出力: Hello!

  return 0;
}

例 3: 単一文字の連結

#include <string>

int main() {
  std::string str1 = "Hello";

  // str1 に単一文字を連結
  str1.append('?');
  std::cout << str1 << std::endl; // 出力: Hello?

  return 0;
}

例 4: サブストリングの連結

#include <string>

int main() {
  std::string str1 = "Hello";
  std::string str2 = "World";

  // str2 の一部を str1 に連結
  str1.append(str2, 1, 4); // "World" の 2 番目から 5 番目の文字 (lowo) を連結
  std::cout << str1 << std::endl; // 出力: Hellolowo

  return 0;
}

例 5: 初期化リストを使用した連結

#include <string>

int main() {
  std::string str1;

  // 初期化リストを使って str1 に文字列を連結
  str1.append({'H', 'e', 'l', 'l', 'o'});
  std::cout << str1 << std::endl; // 出力: Hello

  return 0;
}

これらの例は、std::basic_string::append 関数の基本的な使用方法を示しています。実際の使用場面では、状況に応じて適切なオーバーロードを選択する必要があります。

  • C++11 以降では、std::basic_string_view を使用することで、パフォーマンスを向上させることができます。
  • 連結する文字列の長さを事前に把握しておくことが望ましいです。そうでない場合、メモリ再割り当てが発生し、パフォーマンスが低下する可能性があります。


+= 演算子

最も単純な代替方法は、+= 演算子を使用することです。これは以下のようになります。

std::string str1 = "Hello";
std::string str2 = "World";

str1 += str2;

この方法は簡潔で読みやすいですが、以下の点に注意する必要があります。

  • テンプレート演算子ではないため、コンパイルエラーが発生する可能性があります。
  • 参照渡しではなく値渡しが行われるため、大きな文字列を連結する場合は非効率になる可能性があります。

std::operator+

std::operator+ を使用して、2 つの std::basic_string オブジェクトを連結することもできます。

std::string str1 = "Hello";
std::string str2 = "World";
std::string str3 = str1 + str2;

この方法は += 演算子よりも効率的ですが、以下の点に注意する必要があります。

  • テンプレート演算子ではないため、コンパイルエラーが発生する可能性があります。
  • 新しい std::basic_string オブジェクトが生成されるため、元のオブジェクトが変更されない場合は不要なメモリ割り当てが発生する可能性があります。

イテレータを使用したループ

ループを使用して、文字列を要素ごとに連結することもできます。

std::string str1 = "Hello";
std::string str2 = "World";

for (char c : str2) {
  str1.push_back(c);
}

この方法は柔軟性が高いですが、以下の点に注意する必要があります。

  • 範囲ベース for ループを使用しない場合は、イテレータの操作に注意する必要があります。
  • ループを介して要素を個別に操作するため、非効率になる可能性があります。

std::copy アルゴリズム

std::copy アルゴリズムを使用して、文字列を要素ごとにコピーすることもできます。

std::string str1 = "Hello";
std::string str2 = "World";

std::copy(str2.begin(), str2.end(), std::back_inserter(str1));
  • ヘッダー <algorithm> のインクルードが必要になります。
  • アルゴリズムを使用するため、少し複雑になります。

std::string_view

C++11 以降では、std::string_view クラスを使用して、パフォーマンスを向上させることができます。std::string_view は、std::basic_string の軽量なビューであり、コピーやメモリ割り当てのオーバーヘッドを削減します。

#include <string_view>

std::string str1 = "Hello";
std::string_view str2 = "World";

str1.append(str2);

この方法は効率的ですが、以下の点に注意する必要があります。

  • std::string_view は変更不可であり、std::basic_string に変換が必要になる場合があります。
  • C++11 以降でのみ使用できます。

std::basic_string::append の代替方法は状況によって異なります。単純性と可読性を重視する場合は += 演算子を使用し、パフォーマンスを重視する場合は std::string_view を使用するのがおすすめです。状況に応じて適切な方法を選択してください。

  • 連結する文字列が空であるかどうかを確認する必要があります。空文字列を連結すると、予期しない結果になる可能性があります。
  • 連結する文字列の長さを事前に把握しておくことが望ましいです。そうでない場合、メモリ再割り当てが発生し、パフォーマンスが低下する可能性があります。