C++の標準ライブラリにおける「Strings」:`std::basic_string::assign_range` 関数徹底解説


この関数は、以下のプロトタイプを持つテンプレート関数です。

template<typename InputIt>
void assign_range(InputIt first, InputIt last);

ここで、

  • last は、入力範囲の最後のイテレータを指します。
  • first は、入力範囲の最初のイテレータを指します。
  • InputIt は、入力範囲の最初のイテレータ型を表します。

std::basic_string::assign_range の動作は以下の通りです。

  1. 呼び出し側の std::basic_string オブジェクトの内容はクリアされます。
  2. first から last までのイテレータで指される要素が、呼び出し側の std::basic_string オブジェクトにコピーされます。
  3. 呼び出し側の std::basic_string オブジェクトの長さは、コピーされた要素の数に調整されます。

例:std::basic_string::assign_range の使用方法

#include <iostream>
#include <string>

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

  // str1 に str2 の内容を割り当てる
  str1.assign_range(str2.begin(), str2.end());

  std::cout << str1 << std::endl; // 出力: World!

  return 0;
}

この例では、str1.assign_range(str2.begin(), str2.end()) によって、str2 の内容である "World!" が str1 にコピーされます。

std::basic_string::assign_range の利点

  • 呼び出し側の std::basic_string オブジェクトの内容は、明示的にクリアする必要はありません。
  • ヌル文字終端文字列だけでなく、任意の範囲の要素を割り当てることができます。
  • 範囲ベースのイテレータを使用して、効率的に文字列を割り当てることができます。

std::basic_string::assign_range の注意点

  • 入力範囲の要素は、std::basic_string オブジェクトの要素型と互換性のある型である必要があります。
  • 入力範囲のイテレータは、同じコンテナに属する必要があります。
  • 入力範囲は空であっても構いませんが、呼び出し側の std::basic_string オブジェクトは空になります。

std::basic_string::assign_range は、C++ における強力で効率的な文字列割り当て機能です。範囲ベースのイテレータを使用して、任意の範囲の要素を std::basic_string オブジェクトに割り当てることができます。

  • std::basic_string::assign_range は、std::basic_string::assign と同様の機能を提供しますが、範囲ベースのイテレータを使用してより効率的に使用することができます。
  • std::basic_string::assign_range は、C++20 で導入されました。


例 1:std::string オブジェクトへの範囲割り当て

#include <iostream>
#include <string>

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

  // str1 に str2 の内容を割り当てる
  str1.assign_range(str2.begin(), str2.end());

  std::cout << str1 << std::endl; // 出力: World!

  return 0;
}

例 2:std::vector からの範囲割り当て

#include <iostream>
#include <string>
#include <vector>

int main() {
  std::vector<char> char_vec = {'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!'};

  // char_vec の内容を str に割り当てる
  std::string str;
  str.assign_range(char_vec.begin(), char_vec.end());

  std::cout << str << std::endl; // 出力: Hello, World!

  return 0;
}
#include <iostream>
#include <string>

int main() {
  std::string str = "This is a long string.";

  // str の "is a long" 部分を str2 に割り当てる
  std::string str2;
  str2.assign_range(str.begin() + 5, str.begin() + 15);

  std::cout << str2 << std::endl; // 出力: is a long

  return 0;
}


std::basic_string::assign

std::basic_string::assign は、std::basic_string::assign_range と同様の機能を提供する古い関数です。以下のプロトタイプを持つテンプレート関数です。

template<typename InputIt>
void assign(InputIt first, InputIt last);

std::basic_string::assign の動作は、std::basic_string::assign_range とほぼ同じですが、以下の点が異なります。

  • 入力範囲の最後のイテレータを明示的に渡す必要があり、ヌルポインタを渡すと未定義の動作になります。
  • 範囲ベースのイテレータではなく、通常のイテレータを使用する必要があります。

例:std::basic_string::assign の使用方法

#include <iostream>
#include <string>

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

  // str1 に str2 の内容を割り当てる
  str1.assign(str2.begin(), str2.end());

  std::cout << str1 << std::endl; // 出力: World!

  return 0;
}

ループを使用した要素コピー

std::basic_string::assign_range または std::basic_string::assign を使用せずに、ループを使用して要素をコピーすることもできます。以下の例は、この方法を示しています。

例:ループを使用した要素コピー

#include <iostream>
#include <string>

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

  // str1 に str2 の内容を割り当てる
  for (char c : str2) {
    str1.push_back(c);
  }

  std::cout << str1 << std::endl; // 出力: World!

  return 0;
}

アルゴリズムライブラリの使用

C++ の標準ライブラリには、std::copy アルゴリズムなど、要素をコピーするためのアルゴリズムが用意されています。以下の例は、この方法を示しています。

例:std::copy アルゴリズムを使用した要素コピー

#include <iostream>
#include <string>
#include <algorithm>

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

  // str1 に str2 の内容を割り当てる
  std::copy(str2.begin(), str2.end(), std::back_inserter(str1));

  std::cout << str1 << std::endl; // 出力: World!

  return 0;
}

最適な方法の選択

どの方法が最適かは、状況によって異なります。

  • 細かい制御が必要な場合は、ループまたはアルゴリズムライブラリを使用します。
  • 範囲ベースのイテレータを使用できない場合は、std::basic_string::assign を使用します。
  • std::basic_string::assign_range は、C++20 以降で使用できる最も効率的な方法です。
  • 使用しているコンパイラとライブラリのバージョンを考慮する必要があります。
  • コード的可読性を重視する場合は、ループまたはアルゴリズムライブラリを使用する方がわかりやすい場合があります。
  • パフォーマンスが重要な場合は、std::basic_string::assign_range または std::basic_string::assign を使用する必要があります。