0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C++ STL イテレーターのRange access(std::begin等)の概要と一覧

Last updated at Posted at 2020-05-31

Q.std::beginとかstd::dataって何のためにあるの?
A.テンプレート機能を利用してSTLコンテナ、固定長配列、初期化子リスト等に共通の機能を提供するため。

スコープと動作確認環境

  • この記事ではC++20のStandard Template Library(STL)について扱います。
  • サンプルコードの動作確認環境はWindows 10、Visual Studio Community 2019 Preview(Version 16.7.0 Preview 1.0)でC++言語標準をstd:c++latestとした状態です。
  • 未確認ですがC++17も対応していると思います。

まえがき

STLはC++の標準ライブラリの一部であり、よく使う機能をクラスや関数テンプレートで提供する軽量なライブラリです。このノートではstd::beginstd::data等の目的と使い方を紹介します。個人的な目的は規格案やSTLの学習なので、不適切な部分があれば指摘いただけると嬉しいです。

イテレーターのRange access

概要

STLにはstd::beginstd::dataといったstd::vectorのクラス関数と同名の関数テンプレートが定義されています。これらはstd::vectorのようなSTLコンテナクラスだけ使用する場合は不要ですが、固定長配列(T x[N])や初期化子リスト(std::initializer_list)に対して同様の機能を提供したい場合に役立ちます。

C++20規格案では23.7 Range accessに定義されています。

一覧

23.7 Range accessで定義されたイテレーターのRange accessの一覧です。以下の関数は関数テンプレートおよび特殊化によりSTLコンテナクラス、固定長配列、初期化子リストに対して使用できます。

関数 概要
std::begin 最初の要素
std::end 最後の要素
std::cbegin 最初の要素(const)
std::cend 最後の要素(const)
std::rbegin 末尾から最初の要素
std::rend 末尾から最後の要素
std::crbegin 末尾から最初の要素(const)
std::crend 末尾から最後の要素(const)
std::size 符号なしバイトサイズ
std::ssize 符号付きバイトサイズ
std::empty 空判定
std::data 内部メモリのポインタ

サンプルコード

次のコードでstd::cbeginstd::datastd::sizeがSTLコンテナ、初期化子リスト、固定長配列に対して同様の機能を提供すること、std::listのようなデータが不連続なSTLコンテナに対してはstd::dataが提供されないことを確認できます。

# include <iostream>
# include <string>
# include <list>
# include <vector>
// STLコンテナクラスを使用する場合はインクルードされるので不要です。
// #include <iterator>

int main()
{
	std::wstring s = L"abcde";
	std::vector<int> v = {0, 1, 2, 3, 4};
	std::list<int> l = {0, 1, 2, 3, 4};
	int a[5] = {0, 1, 2, 3, 4};
	std::initializer_list<int> il = { 0, 1, 2, 3, 4 };

	std::wcout << *std::cbegin(s) << std::endl; // 'a'
	std::wcout << *std::cbegin(v) << std::endl; // 0
	std::wcout << *std::cbegin(l) << std::endl; // 0
	std::wcout << *std::cbegin(il) << std::endl;// 0
	std::wcout << *std::cbegin(a) << std::endl; // 0

	std::wcout << std::data(s) << std::endl; // "abcde" (<address>)
	std::wcout << std::data(v) << std::endl; // <address>
	// コメントを解除するとコンパイルエラー
	// std::listはデータが連続しないのでstd::dataが適用できない。
	// std::wcout << std::data(l) << std::endl;
	std::wcout << std::data(a) << std::endl; // <address>
	std::wcout << std::data(il) << std::endl;// <address>

	std::wcout << std::size(s) << std::endl; // 5
	std::wcout << std::size(v) << std::endl; // 5
	std::wcout << std::size(l) << std::endl; // 5
	std::wcout << std::size(a) << std::endl; // 5
	std::wcout << std::size(il) << std::endl;// 5

	return 0;
}

それぞれの定義を表示することでSTLコンテナ、固定長配列、初期化子リストに対して適切な関数テンプレートが呼び出されていることが分かります。

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?