C++によるプログラミングに関する世界観3(STL・ライブラリ)です。
ツール関係はC/C++ツールに移動しました。
システムに依存する部分はLinux(システムコール・API)やWindowsプログラミングも参照のこと。
Visual C++/MFCも参照のこと。
C++の標準ライブラリ。
C++では、標準Cライブラリのヘッダは.hを取り除いて先頭にcを付ける。
STLは標準ライブラリとして含まれているC++のテンプレートを活用したライブラリ。何でもできる柔軟性と調和された美しさを持っている。
標準C++ライブラリの一部で、テンプレートを使った基本的なデータ構造を提供するライブラリ。
STLは以下の要素から構成されている。
要素 | 説明 |
---|---|
コンテナ | 複数の連続したデータ(シーケンス)を格納する。 ほかの言語でいう動的にサイズの変化するリスト、あるいはキーと値のあるハッシュ。 |
イテレータ | シーケンスを反復処理できる反復子。 |
アルゴリズム | シーケンスにプログラム的な処理をかけることができる。 |
関数オブジェクト | オブジェクトに関数のような振る舞いを持たせて実行することができる。 ほかの言語でいうlambda式のようなオブジェクトとして扱うことのできるfunctor。 |
STLはこれらの機能をジェネリックなテンプレートを使うことで実現している。
後日注記:STLはC++を使う上では必須の知識です。「C++をマスターするためにはオブジェクト指向やテンプレートを学ぶだけではなく、STLの使い方に習熟する必要がある」と言われます。実際、STLはさまざまな場面でよく使われます。
後日注記:C++のクラスがオブジェクト指向、テンプレートがジェネリックなダックタイピングに相当するなら、STLは動的なデータ構造や関数オブジェクトに相当する。
STLのコンテナは、「複数の値をひとまとめに格納する」ためのクラス。
STLのコンテナでは、テンプレートを使うことで、任意の型の複数の値を持ったコレクションを扱い、要素を格納・取り出しすることができる。
種類と目的に応じて、vector、deque、list、stack、queue、priority_queue、set、multiset、map、multimapなどがある。
これらは、
・要素の順番が意味を持つか(vector, deque, list)、持たないか(set, multiset, map, multimap)
ベクターやリストの場合:
・ランダムアクセスな操作ができるか(vector, deque)、できないか(list)
・末尾への追加・削除の操作だけが高速か(vector)、末尾だけではなく先頭への操作も高速か(deque)、任意の位置への操作も高速か(list)
セットとマップの場合:
・値だけを持つか(set, multiset)、キーと値の両方を持つか(map, multimap)
・セットの場合、重複した値が許されるか(multiset)、許されないか(set)
・マップの場合、重複したキーが許されるか(multimap)、許されないか(map)
などの特徴がある。
また、stackは後入れ先出し(FILO)のスタック、queueは先入れ先出し(FIFO)のキューとなる。priority_queueは優先度の順に取り出す。
詳しくは以下が参考になる。
後日注記:vector以外にも、listやmap、setなどはさまざまな場面で、たとえばアルゴリズムやデータ構造、デザインパターンなどを記述する際に多く使われます。
配列とリストとハッシュやスタックとキューも参照のこと。
2022.11.30
STLでは、反復子を使うことで、コンテナのそれぞれの要素を順番に処理できる。
後日注記:STLのvectorのような可変長の非連続データは、ポインタや添え字でアクセスすることができない。このため、順番に処理するためにイテレータ(反復子)を用いる。
後日注記:反復子は機能によって5種類に分類される。それぞれ、
反復子 | 特徴 |
---|---|
入力反復子 | 前にしか進めない 進む時は一要素ずつしか進められない 読み込みしかできない 読み込みは要素ごとに一回しかできない |
出力反復子 | 書き込みにも使える |
前方向反復子 | 読み書きを何度でもできる |
双方向反復子 | 後ろに戻ることができる |
ランダムアクセス反復子 | 反復子を前後に好きなだけ移動できる |
となる。(Effective C++ 第3版を参考に執筆しました。)
イテレータとジェネレータを参照のこと。
STLでは、アルゴリズムを使うことで、コンテナのそれぞれの要素をソートしたり検索したり一致判断や結合などを行うことができる。
機能 | アルゴリズム |
---|---|
最大値、最小値 | max(最大値を検索) min(最小値を検索) |
コピー、マージ | copy(コピー) merge(シーケンスとシーケンスを結合) swap(値を互い違いに入れ替え) |
一致、カウント | count(個数を数える) equal(シーケンス同士の範囲の一致を調べる) |
検索 | find(範囲内の値を検索) includes(要素が含まれるかどうかの確認) search(シーケンスの中にあるシーケンスの検索) |
ソート | sort(シーケンスをソート) next_permutation(昇順ソートを作成) prev_permutation(降順ソートを作成) |
(標準C++の基礎知識 (Ascii books)を編集して引用しました。)
注記:シーケンスとは「連続量」のことで、連続したデータのことを表す。STL以外では、プログラムの流れのこともシーケンスと呼ぶことがある(シーケンス図など)。
アルゴリズムも参照のこと。
たとえばこんな感じ。
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; int main(void){ vector<string> v; v.push_back("C++"); v.push_back("Python"); v.push_back("Java"); v.push_back("Perl"); sort(v.begin(), v.end()); for (auto iterator = v.begin(); iterator != v.end(); ++iterator) { cout << *iterator << endl; } }
以下のページを参考に執筆しました。
後日注記:vectorにはsize(), push_back(), begin(), end()の各メソッドがあり、size()で配列の要素数を得ることができ、push_back()で配列の最後に要素を追加できます。また、begin()で配列の先頭位置に対するイテレータを、end()で配列の末尾位置に対するイテレータを取得できます。詳しくは以下の書籍が参考になります。
2023.01.20編集
C++では、クラスにoperator()を実装することで、オブジェクトを関数オブジェクト(functor)として扱うことができる。
functorはクラスとして表されるため、インスタンスごとに異なるデータを格納できる。
このため、たとえばさまざまな場合に応じて別のオブジェクトのメソッドを実行するようなクラスとして関数オブジェクトを記述することもできる。
ソートなどのSTLアルゴリズムにはfunctorを渡せるため、STLとfunctorは相性がいい。
2023.05.15
以下のようなサイトが参考になります。
以下の書籍・ページが参考になる。
C++で正規表現を行うためには、std::regexを使う。
正規表現を参照のこと。
C++で文字列を扱うためには、std::stringを使う。
C++でファイルの読み書きを行うには、ifstream(ファイルの読み込み)とofstream(ファイルの書き込み)を使用する。また先頭に#include <fstream>を書く必要がある。
後日注記:Effective C++ 第3版では、宣言用のヘッダファイルと定義用のヘッダファイルを分けることで、コンパイラの依存性をできるだけ少なくするという話が出てきますが、その中で「iosfwd」というヘッダファイルが紹介されています。これはsstream, streambuf, fstream, iostreamなどのヘッダの宣言内容を集めたもので、コンパイル依存性を少なくするために使うことができます。
Linuxシステムコール・APIも参照のこと。
長らく、C/C++にはスレッドの概念がなかった。そのため、プラットフォーム依存のAPIを使う必要があった。UNIXではpthreadを使うのが一般的だった。
だが、C++11ではstd::threadが提供され、C++でもマルチスレッドアプリケーションを開発できるようになった。
並列処理やJava(マルチスレッド)やLinux API(プロセス・メモリ)も参照のこと。
C++の標準ライブラリ以上の強力な標準ライブラリを目指すライブラリ。
Boost.PropertyTreeを使うことで、INI, XML, JSONなどの形式でプロパティ情報(設定情報)を読み書きできる。特にiniファイルを使ってプログラムの設定情報を保存する際に便利。
iniファイルの読み書きは、Windows APIを用いた方法もある。
XMLと文書形式やJavaクラスライブラリ(XML)も参照のこと。
さまざまなBoostライブラリについては、以下のサイトが参考になる。C++で高度な応用アプリケーションの開発を行いたいと思っている人は必見。
boost::serializationによるC++のシリアライズについては、シリアライズを参照のこと。
Boost Graph LibraryによるC++のグラフ操作については、グラフを参照のこと。