std::basic_string::crendの疑問を徹底解説!C++で逆イテレータを使いこなす

2024-05-24

C++ の "Strings" における std::basic_string::crend の詳細解説

std::basic_string::crend は、C++ の標準ライブラリに含まれる std::string クラスのメンバ関数の一つです。この関数は、逆イテレータと呼ばれる特殊なイテレータを返します。逆イテレータは、文字列の要素を逆方向に辿るために使用されます。

std::basic_string::crend の役割

std::basic_string::crend は、文字列の最後の要素の 前の要素 を指す逆イテレータを返します。言い換えると、std::basic_string::crend が返す逆イテレータは、理論上存在する文字列の先頭 を指します。

std::basic_string::crend は、以下のコードのように使用できます。

std::string str = "Hello, World!";
std::string::const_reverse_iterator it = str.crend();

while (it != str.crbegin()) {
  std::cout << *it;
  --it;
}

このコードは、"Hello, World!" という文字列を逆順に表示します。

std::basic_string::crend が返す逆イテレータは、理論上存在する文字列の先頭 を指します。実際には、この文字列の先頭は存在しないため、この逆イテレータにアクセスしようとすると、未定義の動作 が発生する可能性があります。

std::basic_string::crend を使用する代わりに、以下のコードのように std::basic_string::rbegin()-- 演算子を使用して、文字列の最後の要素を指す逆イテレータを取得することができます。

std::string str = "Hello, World!";
std::string::const_reverse_iterator it = str.rbegin();
--it;

このコードは、std::basic_string::crend を使用する例と同様に、"Hello, World!" という文字列を逆順に表示します。

std::basic_string::crend は、C++ の std::string クラスのメンバ関数の一つです。この関数は、文字列の最後の要素の前の要素を指す逆イテレータを返します。std::basic_string::crend を使用する場合は、未定義の動作 に注意する必要があります。

補足

  • std::basic_string::crend は、const_reverse_iterator 型の逆イテレータを返します。


std::basic_string::crend を使ったサンプルコード

文字列を逆順に表示

#include <iostream>
#include <string>

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

  std::string::const_reverse_iterator it = str.crend();
  while (it != str.crbegin()) {
    std::cout << *it;
    --it;
  }

  return 0;
}

文字列の偶数番目の文字のみを表示

#include <iostream>
#include <string>

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

  std::string::const_reverse_iterator it = str.crend();
  while (it != str.crbegin()) {
    if ((it - str.crbegin()) % 2 == 0) {
      std::cout << *it;
    }
    --it;
  }

  return 0;
}

文字列にある特定の文字列が含まれるかどうかを調べる

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World! How are you?";
  std::string target = "World";

  std::string::const_reverse_iterator it = str.crend();
  while (it != str.crbegin()) {
    for (char c : target) {
      if (*it != c) {
        goto not_found;
      }
      --it;
    }

    std::cout << "文字列 '" << target << "' が含まれています。" << std::endl;
    return 0;

  not_found:
    ;
  }

  std::cout << "文字列 '" << target << "' が見つかりませんでした。" << std::endl;
  return 0;
}

このコードは、"Hello, World! How are you?" という文字列に "World" という文字列が含まれているかどうかを調べます。

文字列を反転させる

#include <iostream>
#include <string>

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

  std::string::const_reverse_iterator it1 = str.crend();
  std::string::iterator it2 = str.begin();

  while (it1 != str.crbegin() && it2 != str.end()) {
    std::swap(*it1, *it2);
    ++it2;
    --it1;
  }

  std::cout << str << std::endl;
  return 0;
}

これらの例は、std::basic_string::crend を使って様々な操作を行う方法を示しています。



std::basic_string::crend 以外の方法

std::copy アルゴリズムを使う

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

int main() {
  std::string str = "Hello, World!";
  std::string reversed_str(str.size());

  std::copy(str.rbegin(), str.rend(), reversed_str.begin());

  std::cout << reversed_str << std::endl;
  return 0;
}

このコードは、std::copy アルゴリズムを使って、str の要素を逆順に reversed_str にコピーします。

for ループを使う

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World!";
  std::string reversed_str;

  for (char c : str) {
    reversed_str.push_back(c);
  }

  std::cout << reversed_str << std::endl;
  return 0;
}

ランダムアクセスイテレータを使う

#include <iostream>
#include <string>

int main() {
  std::string str = "Hello, World!";
  std::string reversed_str;

  for (std::string::size_type i = str.size() - 1; i != std::string::npos; --i) {
    reversed_str.push_back(str[i]);
  }

  std::cout << reversed_str << std::endl;
  return 0;
}

メンバー関数を使う

C++20 では、std::string クラスに std::ranges::reverse アルゴリズムを適用する std::string::reverse() メンバー関数が導入されました。

#include <iostream>
#include <string>

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

  str.reverse();

  std::cout << str << std::endl;
  return 0;
}

このコードは、std::string::reverse() メンバー関数を使って、str の要素を反転させます。

上記の方法は、それぞれ異なる長所と短所があります。状況に応じて、適切な方法を選択してください。

std::basic_string::crend を使用する以外にも、文字列を反転させる方法はいくつかあります。状況に応じて、適切な方法を選択してください。