プログラミング > 驚愕するC++ > 標準C++ライブラリ


標準C++ライブラリとは

標準C++ライブラリとは、C++コンパイラに付属するべき、各種アルゴリズムを実装した関数やオペレーティングシステムを操作するファイル操作など基本的な処理をまとめたライブラリです。どのような環境でもこのライブラリの存在を仮定しても良いように標準化されています。

ただし、ライブラリが実際、どのような機械語に翻訳されるかはコンパイラの実装だけでなく、ライブラリの実装次第であり、見かけ上同じでも異なった動作をしている可能性もあります。

標準C++ライブラリは、STLと呼ばれる標準テンプレートライブラリを含んでおり、STLはコンテナ、アルゴリズム、イテレータ、関数オブジェクトなどを含みます。標準C++ライブラリは、そのほか、数値計算、日付管理、スレッド処理、例外処理、文字列などを含むライブラリです。

Cの標準ライブラリ関数

標準Cライブラリのほとんどは、C++に移植されており、以前のライブラリ名の先頭にcをつけ、末尾の.hを省略したヘッダファイル名となっています。例えば、stdio.hは、cstdioとなっています。このヘッダファイルをincludeすればC++でもprintf関数が利用可能です。但し、名前空間がstdであることに注意してください。

イテレータ


文字列


regex


I/O


数値計算


コンテナ

list/☆forward_list

vector

deque

set/multiset

map/multimap

stack/queue

☆array


ユーティリティ

bitset

random

chrono

☆tuple

可変長引数

☆initializer_list

☆bind


☆スレッド

☆thread

C++11で追加されたライブラリです。標準ライブラリでスレッドを扱うことができるようになりました。

std::threadクラスで新しくスレッドを作ります。コンストラクタの引数として、({別スレッドで実行する関数、関数オブジェクト、ラムダ式}, 渡したい引数1, 2, 3, ...)を取ります。注目すべきは関数オブジェクトを渡せる点ですね。

#include <iostream>
#include <thread>
using namespace std;

void f() {
	for(int i = 0; i < 10; ++i) {
		cout << i << endl; // 別スレッドでは0から9までの数字を出力します
	}
}

int main(void) {
	thread th(f); // スレッドを作ります。関数fは別スレッドで実行されます

	for(int i = 100; i < 110; ++i) {
		cout << i << endl; // メインスレッドでは100~109までの数字を出力します
	}

	th.join(); // 別スレッドが終了するのを待機します。

	cin.get();
	return 0;
}

実行結果は次のようになります。

0
100
101
102
103
1104

105
106
107
2
108
3
4
109
5
6
7
8
9

ご覧の通り、改行endlを出力する前に他のスレッドが実行されてしまい、表示がおかしいですね。このようにマルチスレッド化の実行では、他のスレッドがいつ実行されるか分かりません。従っていつ実行されても問題ないようにプログラムしなければなりません。

なお、引数に参照を渡す場合はstd::ref(変数名)としなければなりません。

☆mutex

std::mutexでは、そのスレッドをロックし、他のスレッドが実行されないようにすることができます。ただし、mutexはスレッドが開始される前に定義されていなければなりません。

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

mutex g_m;

void f() {
	for(int i = 0; i < 10; ++i) {
		g_m.lock();
		cout << i << endl;
		g_m.unlock();
	}
}

int main(void) {
	thread th(f);
	
	for(int i = 100; i < 110; ++i) {
		g_m.lock();
		cout << i << endl;
		g_m.unlock();
	}
	
	th.join();

	cin.get();
	return 0;
}

mutexは、lockされると他のスレッド上でlockされるところで停止します。そして、unlockされるまで待機します。

☆promise


☆future


☆async

非同期処理を簡単に実現します。以下の例では、async(f, ref(mutex))でmutexの参照を非同期実行関数fに渡し、内部でロックし、データを返します。メインスレッドでは必要になったときにget()メソッドでデータを受け取ります。

#include <iostream>
#include <thread>
#include <mutex>
#include <future>
using namespace std;

int f(mutex& m) {
	m.lock(); // このスレッドは次のunlockまで安全である
	cout << "ok!" << endl;
	m.unlock(); // ここまで
	return 100; // 普通に値を返す
}

int main(void) {
	mutex mutex;
	future<int> data = async(f, ref(mutex));

	mutex.lock(); // このスレッドは次のunlockまで安全
	cout << "threading..." << endl;
	mutex.unlock(); // 改行が出力されたらおしまい

	cout << data.get() << endl; // 非同期な出力dataを受け取る

	cin.get();
	return 0;
}
最終更新:2014年01月19日 23:05