Sun Studio 12: C++ ユーザーズガイド

パート III ライブラリ

第 12 章 ライブラリの使用

ライブラリを使用すると、アプリケーション間でコードを共有したり、非常に大規模なアプリケーションを単純化できます。C++ コンパイラでは、さまざまなライブラリを使用できます。この章では、これらのライブラリの使用方法を説明します。

12.1 C ライブラリ

Solaris オペレーティングシステムでは、いくつかのライブラリが /usr/lib にイン ストールされます。 このライブラリのほとんどは C インタフェースを持っています。デフォルトでは libc および libm ライブラリが CC ドライバによってリンクされます。 ライブラリ libthread は、-mt オプションを指定した場合にのみリンクされます。 それ以外のシステムライブラリをリンクするには、-l オプションでリンク時に指定する必要があります。 たとえば、libdemangle ライブラリをリンクするには、リンク時に -ldemangleCC コマンド行に指定します。


example% CC text.c -ldemangle

C++ コンパイラには、独自の実行時ライブラリが複数あります。すべての C++ アプリケーションは、CC ドライバによってこれらのライブラリとリンクされます。C++ コンパイラには、次の節に示すようにこれ以外にも便利なライブラリがいくつかあります。

12.2 C++ コンパイラ付属のライブラリ

Sun C++ コンパイラには、いくつかのライブラリが添付されています。 これらのライブラリには、互換モード (-compat=4) だけで使用できるもの、標準モード (-compat=5) だけで使用できるもの、あるいは両方のモードで使用できるものがあります。 libgc ライブラリと libdemangle ライブラリには C インタフェースがあり、どちらのモードでもアプリケーションにリンクできます。

次の表に、Sun C++ コンパイラに添付されるライブラリと、それらを使用できるモードを示します。

表 12–1 C++ コンパイラに添付されるライブラリ

ライブラリ 

内容の説明 

使用できるモード 

libstlport

標準ライブラリの STLport 実装 

-compat=5

libstlport_dbg

デバッグモード用 STLport ライブラリ 

-compat=5

libCrun

C++ 実行時 

-compat=5

libCstd

C++ 標準ライブラリ 

-compat=5

libiostream

従来の iostream

-compat=5

libC

C++ 実行時、従来の iostream

-compat=4

libcsunimath

-xia オプションをサポート

-compat=5

libcomplex

complex ライブラリ

-compat=4

librwtool

Tools.h++ 7

-compat=4, -compat=5

librwtool_dbg

デバッグ可能な Tools.h++ 7

-compat=4,-compat=5

libgc

ガベージコレクション 

C インタフェース 

libdemangle

復号化 

C インタフェース 


注 –

STLport、Rogue Wave、または Sun Microsystems C++ ライブラリの構成マクロを再定義したり変更したりしないでください。 ライブラリは C++ コンパイラとともに動作するよう構成および構築されています。libCstd と Tool.h++ は互いに働き合うように構成されているので、その構成マクロを変更すると、プログラムのコンパイルやリンクが行われなくなったり、プログラムが正しく実行されなくなったりします。


12.2.1 C++ ライブラリの説明

これらのライブラリについて簡単に説明します。


file:/opt/SUNWspro/docs/index.html

コンパイラソフトウェアが /opt ディレクトリにインストールされていない場合は、システム上でこのディレクトリに相当するパスをシステム管理者に問い合わせてください。

12.2.2 C++ ライブラリのマニュアルページへのアクセス

この節で説明しているライブラリに関するマニュアルページは次の場所にあります。

これらのマニュアルページにアクセスするには、MANPATH/opt/SUNWspro/man (またはシステム上でこのディレクトリに相当するパス) が含まれていることを確認してください。

C++ ライブラリのマニュアルページにアクセスするには次のとおり入力してください。


example% man library-name

C++ ライブラリの version 4.2 のマニュアルページにアクセスするには次のコマンドを入力してください。


example% man -s 3CC4 library-name

次のアドレスに Web ブラウザでアクセスしてマニュアルページにアクセスすることもできます。


file:/opt/SUNWspro/docs/index.html

12.2.3 デフォルトの C++ ライブラリ

これらのライブラリには、CC ドライバによってデフォルトでリンクされるものと、明示的にリンクしなければならないものがあります。標準モードでは、次のライブラリが CC ドライバによってデフォルトでリンクされます。

-lCstd -lCrun -lm -lc

互換モード (-compat) では、次のライブラリがデフォルトでリンクされます。

-lC -lm -lc

詳細は、「A.2.49 -library=l[ ,l...]」を参照してください。

12.3 関連するライブラリオプション

CC ドライバには、ライブラリを使用するためのオプションがいくつかあります。


example% CC test.cc -library=rwtools7,iostream

example% CC test.cc -library=gc -staticlib=gc

example% CC test.cc -compat=4 -staticlib=libC

example% CC test.cc -library=no%Crun,no%Cstd

デフォルトでは、CC は、指定されたコマンド行オプションに従ってさまざなシステムライブラリをリンクします。-xnolib (または -nolib) を指定した場合、CC は、-l オプションを使用してコマンド行で明示的に指定したライブラリだけをリンクします。 -xnolib または -nolib を使用した場合、-library オプションが存在していても無視されます。

-R オプションは、動的ライブラリの検索パスを実行可能ファイルに組み込むときに使用します。 実行時リンカーは、実行時にこれらのパスを使ってアプリケーションに必要な共有ライブラリを探します。CC ドライバは、デフォルトで -R/opt/SUNWspro/libld に渡します (コンパイラが標準の場所にインストールされている場合)。共有ライブラリのデフォルトパスが実行可能ファイルに組み込まれないようにするには、-norunpath を使用します。

12.4 クラスライブラリの使用

一般に、クラスライブラリを使用するには 2 つの手順が必要です。

  1. ソースコードに適切なヘッダーをインクルードする。

  2. プログラムをオブジェクトライブラリとリンクする。

12.4.1 iostream ライブラリ

C++ コンパイラには、2 通りの iostream が実装されています。

すでに C++ のソースがある場合、そのコードは従来の iostream を使用しており、次の例のような形式になっていると思われます。


// ファイル prog1.cc
#include <iostream.h>

int main() {
    cout << "Hello, world!" << endl;
    return 0;
}

次のコマンドは、互換性モードで prog1.cc をコンパイル、リンクして、prog1 という実行可能なプログラムを生成します。従来の iostream ライブラリは、互換性モードのときにデフォルトでリンクされる libC ライブラリに含まれています。


example% CC -compat prog1.cc -o prog1

次の例では、標準 iostream が使用されています。


// ファイル prog2.cc
#include <iostream>

int main() {
    std::cout << "Hello, world!" << std::endl;
    return 0;
}

次のコマンドは、prog2.cc をコンパイル、リンクして、prog2 という実行可能なプログラムを生成します。コンパイルは標準モードで行われ、このモードでは、標準の iostream ライブラリを含む libCstd がデフォルトでリンクされます。


example% CC prog2.cc -o prog2

libCstd についての詳細は、「警告:」を参照してください。libiostream の詳細は、「13.3.1 再配布とサポートされる STLport ライブラリ」を参照してください。

コンパイルモードの詳しい説明については、『C++ 移行ガイド』を参照してください。

12.4.2 complex ライブラリ

標準ライブラリには、C++ 4.2 コンパイラに付属していた complex ライブラリに似た、テンプレート化された complex ライブラリがあります。標準モードでコンパイルする場合は、<complex> ではなく、<complex.h> を使用する必要があります。互換性モードで <complex> を使用することはできません。

互換性モードでは、リンク時に complex ライブラリを明示的に指定しなければなりません。標準モードでは、complex ライブラリは libCstd に含まれており、デフォルトでリンクされます。

標準モード用の complex.h ヘッダーはありません。C++ 4.2 では、「complex」 はクラス名ですが、標準 C++ では「complex」はテンプレート名です。したがって、旧式のコードを変更せずに動作できるようにする typedef を使用することはできません。このため、複素数を使用する、4.2 用のコードで標準ライブラリを使用するには、多少の編集が必要になります。たとえば、次のコードは 4.2 用に作成されたものであり、互換性モードでコンパイルされます。


// ファイル ex1.cc (互換モード)
#include <iostream.h>
#include <complex.h>

int main()
{
    complex x(3,3), y(4,4);
    complex z = x * y;
    cout << "x=" << x << ", y=" << y << ", z=" << z << endl;
}

次の例では、ex1.cc を互換モードでコンパイル、リンクし、生成されたプログラムを実行しています。


example% CC -compat ex1.cc -library=complex
example% a.out
x=(3, 3), y=(4, 4), z=(0, 24)

次は、標準モードでコンパイルされるように ex2.cc と書き直された ex1.cc です。


// ファイル ex2.cc (ex1.cc を標準モード用に書き直し)
#include <iostream>
#include <complex>
using std::complex;

int main()
{
     complex<double> x(3,3), y(4,4);
     complex<double> z = x * y;
     std::cout << "x=" << x << ", y=" << y << ", z=" << z <<
       std::endl;
}

次の例では、書き直された ex2.cc をコンパイル、リンクして、生成されたプログラムを実行しています。


% CC ex2.cc
% a.out
x=(3,3), y=(4,4), z=(0,24)

複素数演算ライブラリの使用方法についての詳細は、表 14–4を参照してください。

12.4.3 C++ ライブラリのリンク

次の表は、C++ ライブラリにリンクするためのコンパイラオプションをまとめています。詳細は、「A.2.49 -library=l[ ,l...]」を参照してください。

表 12–2 C++ ライブラリにリンクするためのコンパイラオプション

ライブラリ 

コンパイルモード 

オプション 

従来の iostream

-compat=4

-compat=5

不要 

-library=iostream

complex

-compat=4

-compat=5

-library=complex

不要 

Tools.h++ version 7

-compat=4

-compat=5

-library=rwtools7

-library=rwtools7,iostream

-library=rwtools7_std

デバッグ対応 Tools.h++ version 7

-compat=4

-compat=5

-library=rwtools7_dbg

-library=rwtools7_dbg,iostream

-library=rwtools7_std_dbg

ガベージコレクション

-compat=4

-compat=5

-library=gc

-library=gc

STLport version 4 

-compat=5

-library=stlport4

STLport version 4 デバッグ 

-compat=5

-library=stlport4_dbg

12.5 標準ライブラリの静的リンク

デフォルト時、CC ドライバは、デフォルトライブラリの -llib オプションをリンカーに渡すことによって、libclibm を含むいくつかのライブラリの共有バージョンでリンクします。互換性モードと標準モードにおけるデフォルトライブラリのリストについては、「12.2.3 デフォルトの C++ ライブラリ」を参照してください。

このようにデフォルトのライブラリを静的にリンクする場合、-library オプションと -staticlib オプションを一緒に使用すれば、C++ ライブラリを静的にリンクできます。 この方法は、以前説明した方法よりもかなり簡単です。次に例を示します。


example% CC test.c -staticlib=Crun

この例では、-library オプションが明示的にコマンドに指定されていません。標準モード (デフォルトのモード) では、-library のデフォルトの設定が Cstd,Crun であるため、-library オプションを明示的に指定する必要はありません。

あるいは、-xnolib コンパイラオプションも使用できます。-xnolib オプションを指定すると、ドライバは自動的には -l オプションを ld に渡しません。次の例は、Solaris 8 または Solaris 9 オペレーティングシステムで libCrun と静的に、libm および libc と動的にリンクする方法を示します。


example% CC test.c- xnolib- lCstd- Bstatic- lCrun- Bdynamic lm- lc

-l オプションの順序は重要です。-lCstd-lCrun、および -lm オプションは、-lc の前に指定します。

ほかのライブラリにリンクする CC オプションもあります。そうしたライブラリへのリンクも -xnolib によって行われないように設定できます。たとえば、-mt オプションを指定すると、CC ドライバは、-lthreadld に渡します。 これに対し、-mt-xnolib の両方を使用すると、CC ドライバは ld-lthread を渡しません。詳細は、「A.2.146 -xnolibを参照してください。ld については、Solaris に関するマニュアル『リンカーとライブラリ』を参照してください。

12.6 共有ライブラリの使用

C++ コンパイラには、次の共有ライブラリが含まれています。

プログラムにリンクされた各共有オブジェクトは、生成される実行可能ファイル (a.out ファイル) に記録されます。 この情報は、実行時に ld.so が使用して動的リンク編集を行います。ライブラリコードをアドレス空間に実際に組み込むのはあとになるため、共有ライブラリを使用するプログラムの実行時の動作は、環境の変化、つまり、ライブラリを別のディレクトリに移動することに影響を受けます。たとえば、プログラムが /opt/SUNWspro/liblibcomplex.so.5 とリンクされている場合、あとで libcomplex.so.5 ライブラリを /opt2/SUNWspro/lib に移動すると、このバイナリコードを実行したときに次のメッセージが表示されます。


ld.so: libcomplex.so.5: ファイルもディレクトリもありません

ただし、環境変数 LD_LIBRARY_PATH に新しいライブラリの ディレクトリを設定すれば、古いバイナリコードを再コンパイルせずに実行できます。

C シェルでは次のように入力します。


example% setenv LD_LIBRARY_PATH \
/opt2/SUNWspro/release/lib:${LD_LIBRARY_PATH}

Bourne シェルでは次のように入力します。


example$ LD_LIBRARY_PATH=\
/opt2/SUNWspro/release/lib:${LD_LIBRARY_PATH}
example$ export LD_LIBRARY_PATH

注 –

release は、コンパイラソフトウェアのそれぞれのリリースによって異なります。


LD_BINARY_PATH には、ディレクトリのリストが含まれています。 ディレクトリは通常コロンで区切られています。C++ プログラムを実行すると、動的ローダーがデフォルトディレクトリより前に LD_BINARY_PATH のディレクトリを検索します。

実行可能ファイルにどのライブラリが動的にリンクされるのかを知るには、ldd コマンドを使用します。


example% ldd a.out

共有ライブラリを移動することはめったにないので、この手順が必要になることはほとんどありません。


注 –

共有ライブラリを dlopen で開く場合は、RTLD_GLOBAL を使用しないと例外が機能しません。


共有ライブラリの詳しい使い方については、『リンカーとライブラリ』を参照してください。

12.7 C++ 標準ライブラリの置き換え

ただし、コンパイラに添付された標準ライブラリを置き換えることは危険で、必ずしもよい結果につながるわけではありません。基本的な操作としては、コンパイラに添付されている標準のヘッダーとライブラリを無効にして、新しいヘッダーファイルとライブラリが格納されているディレクトリとライブラリ自身の名前を指定します。

コンパイラは、標準ライブラリの STLport 実装をサポートします。詳細は、「13.3 STLport」を参照してください。

12.7.1 置き換え可能な対象

ほとんどの標準ライブラリおよびそれに関連するヘッダーは置き換え可能です。 たとえば libCstd ライブラリを別のものに置き換える場合は、次の関連するヘッダーも置き換える必要があります。


<algorithm> <bitset> <complex> <deque> <fstream <functional> <iomanip> <ios> <iosfwd> <iostream> <istream> <iterator> <limits> <list> <locale> <map> <memory> <numeric> <ostream> <queue> <set> <sstream> <stack> <stdexcept> <streambuf> <string> <strstream> <utility> <valarray> <vector>

ライブラリの置き換え可能な部分は、いわゆる「STL」と呼ばれているもの、文字列クラス、iostream クラス、およびそれらの補助クラスです。このようなクラスとヘッダーは相互に依存しているため、それらの一部を置き換えるだけでは通常は機能しません。一部を変更する場合でも、すべてのヘッダーと libCstd のすべてを置き換える必要があります。

12.7.2 置き換え不可能な対象

標準ヘッダー <exception><new>、および <typeinfo> は、コンパイラ自身とlibCrun に密接に関連しているため、これらを置き換えることは安全ではありません。ライブラリ libCrun は、コンパイラが依存している多くの「補助」関数が含まれているため置き換えることはできません。

C から派生した 17 個の標準ヘッダー (<stdlib.h><stdio.h><string.h> など) は、Solaris オペレーティングシステムと基本 Solaris 実行時ライブラリ libc に密接に関連しているため、これらを置き換えることは安全ではありません。これらのヘッダーの C++ 版 (<cstdlib><cstdio><cstring> など) は基本の C 版のヘッダーに密接に関連しているため、これらを置き換えることは安全ではありません。

12.7.3 代替ライブラリのインストール

代替ライブラリをインストールするには、まず、代替ヘッダーの位置と libCstd の代わりに使用するライブラリを決定する必要があります。理解しやすくするために、ここでは、ヘッダーを /opt/mycstd/include にインストールし、ライブラリを /opt/mycstd/lib にインストールすると仮定します。ライブラリの名前は libmyCstd.a であると仮定します。なお、ライブラリの名前を lib で始めると後々便利です。

12.7.4 代替ライブラリの使用

コンパイルごとに -I オプションを指定して、ヘッダーがインストールされている位置を指示します。さらに、 -library=no%Cstd オプションを指定して、コンパイラ独自のバージョンの libCstd ヘッダーが検出されないようにします。次に例を示します。


example% CC -I/opt/mycstd/include -library=no%Cstd... (コンパイルの場合)

-library=no%Cstd オプションを指定しているため、コンパイル中、コンパイラ独自のバージョンのヘッダーがインストールされているディレクトリは検索されません。

プログラムまたはライブラリのリンクごとに -library=no%Cstd オプションを指定して、コンパイラ独自の libCstd が検出されないようにします。 さらに、-L オプションを指定して、代替ライブラリがインストールされているディレクトリを指示します。 さらに、-l オプションを指定して、代替ライブラリを指定します。次に例を示します。


example% CC -library=no%Cstd -L/opt/mycstd/lib -lmyCstd... (リンクの場合)

あるいは、-L-l オプションを使用せずに、ライブラリの絶対パス名を直接指定することもできます。次に例を示します。


example% CC -library=no%Cstd /opt/mycstd/lib/libmyCstd.a... (リンクの場合)

-library=no%Cstd オプションを指定しているため、リンク中、コンパイラ独自のバージョンの libCstd はリンクされません。

12.7.5 標準ヘッダーの実装

C には、<stdio.h><string.h><stdlib.h> などの 17 個の標準ヘッダーがあります。これらのヘッダーは Solaris オペレーティングシステムに標準で付属しており、/user/include に置かれています。C++ にも同様のヘッダーがありますが、さまざまな宣言の名前が大域の名前空間と std 名前空間の両方に存在するという条件が付加されています。version 8 より前のリリースの Solaris オペレーティングシステムの C++ コンパイラでは、/usr/include ディレクトリにあるヘッダーはそのまま残して、独自のバージョンのヘッダーを別に用意しています。

また、C++ には、C 標準ヘッダー (<cstdio><cstring><cstdlib> など) のそれぞれについても専用のバージョンがあります。 C++ 版の C 標準ヘッダーでは、宣言名は std 名前空間にのみ存在します。C++ には、32 個の独自の標準ヘッダー (<string><utility><iostream> など) も追加されています。

標準ヘッダーの実装で、C++ ソースコード内の名前がインクルードするテキストファイル名として使用されているとしましょう。たとえば、標準ヘッダーの <string> (または <string.h>) が、あるディレクトリにある string (または string.h) というファイルを参照するものとします。この実装には、次の欠点があります。

こうした問題を解決するため、コンパイラの include ディレクトリには、ヘッダーと同じ名前を持つファイルと、一意の接尾辞 .SUNWCCh を持つ、そのファイルへのシンボリックリンクが含まれています。SUNW はコンパイラに関係するあらゆるパッケージに対する接頭辞、CC は C++ コンパイラの意味、.h はヘッダーファイルの通常の接尾辞です。 つまり <string> と指定された場合、コンパイラは <string.SUNWCCh> と書き換え、その名前を検索します。接尾辞付きの名前は、コンパイラ専用の include ディレクトリにだけ存在します。このようにして見つけられたファイルがシンボリックリンクの場合 (通常はそうである)、コンパイラは、エラーメッセージやデバッガの参照でそのリンクを 1 回だけ間接参照し、その参照結果 (この場合は string) をファイル名として使用します。ファイルの依存関係情報を送るときは、接尾辞付きの名前の方が使用されます。

この名前の書き換えは、2 つのバージョンがある 17 個の標準 C ヘッダーと 32 個の標準 C++ ヘッダーのいずれかを、パスを指定せずに山括弧 < > で囲んで指定した場合にだけ行われます。山括弧の代わりに引用符が使用されるか、パスが指定されるか、ほかのヘッダーが指定された場合、名前の書き換えは行われません。

次の表は、よくある書き換え例をまとめています。

表 12–3 ヘッダー検索の例

ソースコード 

コンパイラによる検索 

注釈 

<string>

string.SUNWCCh

C++ の文字列テンプレート 

<cstring>

cstring.SUNWCCh

C の string.h の C++ 版

<string.h>

string.h.SUNWCCh

C の string.h

<fcntl.h>

fcntl.h

標準 C および C++ ヘッダー以外 

"string"

string

山括弧ではなく、二重引用符 

<../string>

../string

パス指定がある場合 

コンパイラが header.SUNWCCh (header はヘッダー名) を見つけることができなかった場合、コンパイラは、#include 指令で指定された名前で検索をやり直します。たとえば、#include <string> という指令を指定した場合、コンパイラは string.SUNWCCh という名前のファイルを見つけようとします。この検索が失敗した場合、コンパイラは string という名前のファイルを探します。

12.7.5.1 標準 C++ ヘッダーの置き換え

「12.7.5 標準ヘッダーの実装」で説明している検索アルゴリズムのため、「12.7.3 代替ライブラリのインストール」で説明している SUNWCCh 版の代替 ヘッダーを指定する必要はありません。しかし、これまでに説明したいくつかの問題が発生する可能性もあります。その場合、推奨される解決方法は、接尾辞が付いていないヘッダーごとに、接尾辞 .SUNWCCh を持つファイルに対してシンボリックリンクを作成することです。つまり、ファイルが utility の場合、次のコマンドを実行します。


example% ln -s utility utility.SUNWCCh

utility.SUNWCCh というファイルを探すとき、コンパイラは 1 回目の検索でこのファイルを見つけます。 そのため、utility という名前のほかのファイルやディレクトリを誤って検出してしまうことはありません。

12.7.5.2 標準 C ヘッダーの置き換え

標準 C ヘッダーの置き換えはサポートされていません。それでもなお、独自のバージョンの標準ヘッダーを使用したい場合、推奨される手順は次のとおりです。

たとえば、<stdio.h><cstdio> の代替ヘッダーとして stdio.h と cstdio を使用するとします。stdio.hcstdio をディレクトリ /myproject/myhdr に置きます。このディレクトリ内で、次のコマンドを実行します。


example% ln -s stdio.h stdio.h.SUNWCCh
example% ln -s cstdio cstdio.SUNWCCh

コンパイルのたびに、オプション -I/myproject/mydir を使用します。

警告:

第 13 章 C++ 標準ライブラリの使用

デフォルトモード (標準モード) のコンパイルでは、コンパイラは C++ 標準で指定されている完全なライブラリにアクセスします。このライブラリには、非公式に「標準テンプレートライブラリ」 (STL) と呼ばれているものに加えて、次の要素が含まれています。

STL は公式なものではありませんが、一般的にはコンテナ、反復子、アルゴリズムから構成されます。標準ライブラリのヘッダーのうち、次のものを STL の構成要素と見なすことができます。

C++ 標準ライブラリ (libCstd) は、RogueWaveTM の標準 C++ ライブラリに基づいています。このライブラリはデフォルトモード (-compat=5) だけで使用することができます。-compat[=4] オプションを使用した場合はサポートされません。

また、C++ コンパイラで、STLport の標準ライブラリの version 4.5.3 がサポートされました。libCstd がデフォルトのライブラリですが、代わりに STLport の製品を使用できるようになりました。詳細は、「13.3 STLport」を参照してください。

コンパイラに付属している C++ 標準ライブラリの代わりに、独自の C++ 標準ライブラリを使用できます。その場合は、-library=no%Cstd オプションを使用します。ただし、コンパイラに添付された標準ライブラリを置き換えることは危険で、必ずしもよい結果につながるわけではありません。詳細は、「12.7 C++ 標準ライブラリの置き換え」を参照してください。

標準ライブラリの詳細については、『標準 C++ ライブラリ・ユーザーズガイド』と『Standard C++ Class Library Reference』(英語版) を参照してください。 これらの文書へのアクセス方法については、本書の冒頭にある「はじめに」の「Sun Studio マニュアルへのアクセス方法」を参照してください。また、C++ 標準ライブラリについての参考書については、「はじめに」の「市販の書籍」を参照してください。

13.1 C++ 標準ライブラリのヘッダーファイル

標準ライブラリのヘッダーとその概要を表 13–1 に示します。

表 13–1 C++ 標準ライブラリのヘッダーファイル

ヘッダーファイル 

内容の説明 

<algorithm>

コンテナ操作のための標準アルゴリズム 

<bitset>

固定長のビットシーケンス 

<complex>

複素数を表す数値型 

<deque>

先頭と末尾の両方で挿入と削除が可能なシーケンス 

<exception>

事前定義済み例外クラス 

<fstream>

ファイルとのストリーム入出力 

<functional>

関数オブジェクト 

<iomanip>

iostream のマニピュレータ

<ios>

iostream の基底クラス

<iosfwd>

iostream クラスの先行宣言

<iostream>

基本的なストリーム入出力機能 

<istream>

入力ストリーム 

<iterator>

シーケンスの内容にくまなくアクセスするためのクラス 

<limits>

数値型の属性 

<list>

順序付きシーケンス 

<locale>

国際化のサポート 

<map>

キーと値を対にして使用する連想コンテナ 

<memory>

特殊なメモリーアロケータ 

<new>

基本的なメモリー割り当てと解放 

<numeric>

汎用の数値演算 

<ostream>

出力ストリーム 

<queue>

先頭への挿入と末尾からの削除が可能なシーケンス 

<set>

一意キーを使用する連想コンテナ 

<sstream>

メモリー上の文字列との入出力ストリーム 

<stack>

先頭への挿入と先頭からの削除が可能なシーケンス 

<stdexcept>

追加標準例外クラス 

<streambuf>

iostream 用のバッファークラス 

<string>

文字シーケンス 

<typeinfo>

実行時の型識別 

<utility>

比較演算子 

<valarray>

数値プログラミング用の値配列 

<vector>

ランダムアクセスが可能なシーケンス 

13.2 C++ 標準ライブラリのマニュアルページ

標準ライブラリの個々の構成要素のマニュアルページを表 13–2 に示します。

表 13–2 C++ 標準ライブラリのマニュアルページ

マニュアルページ 

概要 

Algorithms

コンテナとシーケンスに各種処理を行うための汎用アルゴリズム 

Associative_Containers

特定の順序で並んだコンテナ 

Bidirectional_Iterators

読み書きの両方が可能で、順方向、逆方向にコンテナをたどることができる反復子 

Containers

標準テンプレートライブラリ (STL) コレクション 

Forward_Iterators

読み書きの両方が可能な順方向反復子 

Function_Objects

operator() が定義済みのオブジェクト

Heap_Operations

make_heappop_heappush_heapsort_heap を参照

Input_Iterators

読み取り専用の順方向反復子 

Insert_Iterators

反復子がコンテナ内の要素を上書きせずにコンテナに挿入することを可能にする、反復子アダプタ 

Iterators

コレクションをたどったり、変更したりするためのポインタ汎用化機能 

Negators

述語関数オブジェクトの意味を逆にするための関数アダプタと関数オブジェクト 

Operators

C++ 標準テンプレートライブラリ出力用の演算子 

Output_Iterators

書き込み専用の順方向反復子 

Predicates

ブール値 (真偽) または整数値を返す関数または関数オブジェクト 

Random_Access_Iterators

コンテナの読み取りと書き込みをして、コンテナにランダムアクセスすることを可能にする反復子 

Sequences

一群のシーケンスをまとめたコンテナ 

Stream_Iterators

汎用アルゴリズムをストリームに直接に使用することを可能にする、ostream と istream 用の反復子機能を含む 

__distance_type

反復子が使用する距離のタイプを決定する (廃止予定) 

__iterator_category

反復子が属するカテゴリを決定する (廃止予定) 

__reverse_bi_iterator

コレクションを逆方向にたどる反復子 

accumulate

1 つの範囲内のすべての要素の累積値を求める 

adjacent_difference

1 つの範囲内の隣り合う 2 つの要素の差のシーケンスを出力する 

adjacent_find

シーケンスから、等しい値を持つ最初の 2 つの要素を検出する 

advance

特定の距離で、順方向または逆方向 (使用可能な場合) に反復子を移動する 

allocator

標準ライブラリコンテナ内の記憶管理用のデフォルトの割り当てオブジェクト 

auto_ptr

単純でスマートなポインタクラス 

back_insert_iterator

コレクションの末尾への項目の挿入に使用する挿入反復子 

back_inserter

コレクションの末尾への項目の挿入に使用する挿入反復子 

basic_filebuf

入力または出力シーケンスをファイルに関連付ける 

basic_fstream

1 つのファイル記述子に関連付けられた、複数の指定ファイルまたはその他デバイスに対する読み書きをサポートする 

basic_ifstream

1 つのファイル記述子に関連付けられた、複数の指定ファイルまたはその他デバイスからの読み取りをサポートする 

basic_ios

すべてのストリームが共通に必要とする関数を取り込む基底クラス 

basic_iostream

ストリームバッファーが制御する文字シーケンスの書式設定と解釈をサポートする 

basic_istream

ストリームバッファーが制御する文字シーケンスからの入力の読み取りと解釈をサポートする 

basic_istringstream

メモリー上の配列からの basic_string<charT,traits,Allocator> クラスのオブジェクトの読み取りをサポートする

basic_ofstream

1 つのファイル記述子に関連付けられた、複数の指定ファイルまたはその他デバイスへの書き込みをサポートする 

basic_ostream

ストリームバッファーが制御するシーケンスに対する出力の書式設定と書き込みをサポートする 

basic_ostringstream

basic_string<charT,traits,Allocator> クラスのオブジェクトの書き込みをサポートする

basic_streambuf

各種のストリームバッファーを派生させて、 文字シーケンスを制御しやすいようにする抽象基底クラス 

basic_string

文字に似た要素シーケンスを処理するためのテンプレート化されたクラス 

basic_stringbuf

入力または出力シーケンスを任意の文字シーケンスに関連付ける 

basic_stringstream

メモリー上の配列に対する basic_string<charT,traits,Allocator> クラスのオブジェクトの書き込みと読み取りをサポートする

binary_function

2 項関数オブジェクトを作成するための基底クラス 

binary_negate

2 項判定子の結果の補数を返す関数オブジェクト 

binary_search

コンテナ上の値について 2 等分検索を行う 

bind1st

関数オブジェクトに値を結合するためのテンプレート化されたユーティリティー 

bind2nd

関数オブジェクトに値を結合するためのテンプレート化されたユーティリティー 

binder1st

関数オブジェクトに値を結合するためのテンプレート化されたユーティリティー 

binder2nd

関数オブジェクトに値を結合するためのテンプレート化されたユーティリティー 

bitset

固定長のビットシーケンスを格納、操作するためのテンプレートクラスと関数 

cerr

<cstdio> で宣言されたオブジェクトの stderr に関連付けられたバッファリングなしストリームバッファーに対する出力を制御する

char_traits

basic_string コンテナと iostream クラス用の型と演算を持つ特性 (traits) クラス

cin

<cstdio> で宣言されたオブジェクトの stdin に関連付けられたストリームバッファーからの入力を制御する

clog

<cstdio> で宣言されたオブジェクトの stderr に関連付けられたストリームバッファーに対する出力を制御する

codecvt

コード変換ファセット 

codecvt_byname

指定ロケールに基づいたコードセット変換分類機能を含むファセット 

collate

文字列照合、比較、ハッシュファセット 

collate_byname

文字列照合、比較、ハッシュファセット 

compare

真または偽を返す 2 項関数または関数オブジェクト 

complex

C++ 複素数ライブラリ 

copy

ある範囲の要素をコピーする 

copy_backward

ある範囲の要素をコピーする 

count

指定条件を満たすコンテナ内の要素の個数をカウントする 

count_if

指定条件を満たすコンテナ内の要素の個数をカウントする 

cout

<cstdio> で宣言されたオブジェクトの stderr に関連付けられたストリームバッファーに対する出力を制御する

ctype

文字分類機能を取り込むファセット 

ctype_byname

指定ロケールに基づいた文字分類機能を含むファセット 

deque

ランダムアクセス反復子と、先頭および末尾の両方での効率的な挿入と削除をサポートするシーケンス 

distance

2 つの反復子間の距離を求める 

divides

1 つ目の引数を 2 つ目の引数で除算した結果を返す 

equal

2 つのある範囲が等しいかどうか比較する 

equal_range

並べ替えの順序を崩さずに値を挿入できる最大の二次範囲をコレクションから検出する 

equal_to

1 つ目と 2 つ目の引数が等しい場合に真を返す 2 項関数オブジェクト 

exception

倫理エラーと実行時エラーをサポートするクラス 

facets

複数種類のロケール機能をカプセル化するために使用するクラス群 

filebuf

入力または出力シーケンスをファイルに関連付ける 

fill

指定された値である範囲を初期化する 

fill_n

指定された値である範囲を初期化する 

find

シーケンスから値に一致するものを検出する 

find_end

シーケンスからサブシーケンスに最後に一致するものを検出する 

find_first_of

シーケンスから、別のシーケンスの任意の値に一致するものを検出する 

find_if

シーケンスから指定された判定子を満たす値に一致するものを検出する 

for_each

ある範囲のすべての要素に関数を適用する 

fpos

iostream クラスの位置情報を保持する 

front_insert_iterator

コレクションの先頭に項目を挿入するための挿入反復子 

front_inserter

コレクションの先頭に項目を挿入するための挿入反復子 

fstream

1 つのファイル記述子に関連付けられた、複数の指定ファイルまたはその他デバイスに対する読み書きをサポートする 

generate

値生成クラスによって生成された値でコンテナを初期化する 

generate_n

値生成クラスによって生成された値でコンテナを初期化する 

get_temporary_buffer

メモリーを処理するためのポインタベースのプリミティブ 

greater

1 つ目の引数が 2 つ目の引数より大きい場合に真を返す 2 項関数オブジェクト 

greater_equal

1 つ目の引数が 2 つ目の引数より大きいか等しい場合に真を返す 2 項関数オブジェクト 

gslice

配列から汎用化されたスライスを表現するために使用される数値配列クラス 

gslice_array

valarray から BLAS に似たスライスを表現するために使用される数値配列クラス 

has_facet

ロケールに指定ファセットがあるかどうかを判定するための関数テンプレート 

ifstream

1 つのファイル記述子に関連付けられた、複数の指定ファイルまたはその他デバイスからの読み取りをサポートする 

includes

ソートされたシーケンスに対する基本演算セット 

indirect_array

valarray から選択された要素の表現に使用される数値配列クラス 

inner_product

2 つの範囲 A および B の内積 (A × B) を求める 

inplace_merge

ソートされた 2 つのシーケンスを 1 つにマージする 

insert_iterator

コレクションを上書きせずにコレクションに項目を挿入するときに使用する挿入反復子 

inserter

コレクションを上書きせずにコレクションに項目を挿入するときに使用する挿入反復子 

ios

すべてのストリームが共通に必要とする関数を取り込む基底クラス 

ios_base

メンバーの型を定義して、そのメンバーから継承するクラスのデータを保持する 

iosfwd

入出力ライブラリテンプレートクラスを宣言し、 そのクラスを wide および tiny 型文字専用にする 

isalnum

文字が英字または数字のどちらであるかを判定する 

isalpha

文字が英字であるかどうかを判定する 

iscntrl

文字が制御文字であるかどうかを判定する 

isdigit

文字が 10 進数であるかどうかを判定する 

isgraph

文字が図形文字であるかどうかを判定する 

islower

文字が英小文字であるかどうかを判定する 

isprint

文字が印刷可能かどうかを判定する 

ispunct

文字が区切り文字であるかどうかを判定する 

isspace

文字が空白文字であるかどうかを判定する 

istream

ストリームバッファーが制御する文字シーケンスからの入力の読み取りと解釈をサポートする 

istream_iterator

istream に対する反復子機能を持つストリーム反復子 

istreambuf_iterator

作成元のストリームバッファーから連続する文字を読み取る 

istringstream

メモリー上の配列からの basic_string<charT,traits,Alocator> クラスのオブジェクトの読み取りをサポートする

istrstream

メモリー上の配列から文字を読み取る 

isupper

文字が英大文字であるかどうかを判定する 

isxdigit

文字が 16 進数であるかどうかを判定する 

iter_swap

2 つの位置の値を交換する 

iterator

基底反復子クラス 

iterator_traits

反復子に関する基本的な情報を返す 

less

1 つ目の引数が 2 つ目の引数より小さい場合に真を返す 2 項関数オブジェクト 

less_equal

1 つ目の引数が 2 つ目の引数より小さいか、等しい場合に真を返す 2 項関数オブジェクト 

lexicographical_compare

2 つの範囲を辞書式に比較する 

limits

numeric_limits セクションを参照

list

双方向反復子をサポートするシーケンス 

locale

多相性を持つ複数のファセットからなるローカリゼーションクラス 

logical_and

1 つ目の 2 つ目の引数が等しい場合に真を返す場合に 2 項関数オブジェクト 

logical_not

引数が偽の場合に真を返す単項関数オブジェクト 

logical_or

引数のいずれかが真の場合に真を返す 2 項関数オブジェクト 

lower_bound

ソートされたコンテナ内の最初に有効な要素位置を求める 

make_heap

ヒープを作成する 

map

一意のキーを使用してキー以外の値にアクセスする連想コンテナ 

mask_array

valarray の選別ビューを提供する数値配列クラス 

max

2 つの値の大きい方の値を検出して返す 

max_element

1 つの範囲内の最大値を検出する 

mem_fun

大域関数の代わりとしてポインタをメンバー関数に適合させる関数オブジェクト 

mem_fun1

大域関数の代わりとしてポインタをメンバー関数に適合させる関数オブジェクト 

mem_fun_ref

大域関数の代わりとしてポインタをメンバー関数に適合させる関数オブジェクト 

mem_fun_ref1

大域関数の代わりとしてポインタをメンバー関数に適合させる関数オブジェクト 

merge

ソートされた 2 つのシーケンスをマージして、 3 つ目のシーケンスを作成する 

messages

メッセージ伝達ファセット 

messages_byname

メッセージ伝達ファセット 

min

2 つの値の小さい方の値を検出して返す 

min_element

1 つの範囲内の最小値を検出する 

minus

1 つ目の引数から 2 つ目の引数を減算した結果を返す 

mismatch

2 つのシーケンスの要素を比較して、互いに値が一致しない最初の 2 つの要素を返す 

modulus

1 つ目の引数を 2 つ目の引数で除算することによって得られた余りを返す 

money_get

入力に対する通貨書式設定ファセット 

money_put

出力に対する通貨書式設定ファセット 

moneypunct

通貨句読文字ファセット 

moneypunct_byname

通貨句読文字ファセット 

multimap

キーを使用してコンテナキーでない値にアクセスするための連想コンテナ 

multiplies

1 つ目と 2 つ目の引数を乗算した結果を返す 2 項関数オブジェクト 

multiset

格納済みのキー値に高速アクセスするための連想コンテナ 

negate

引数の否定値を返す単項関数オブジェクト 

next_permutation

並べ替え関数に基づいてシーケンスの内容を連続的に入れ替えたものを生成する 

not1

単項述語関数オブジェクトの意味を逆にするための関数アダプタ 

not2

単項述語関数オブジェクトの意味を逆にするための関数アダプタ 

not_equal_to

1 つ目の引数が 2 つ目の引数と等しくない場合に真を返す 2 項関数オブジェクト 

nth_element

コレクションを再編して、ソートで n 番目の要素よりあとになった全要素をその要素より前に、n 番目の要素より前の全要素をその要素より後ろにくるようにする

num_get

入力に対する書式設定ファセット 

num_put

出力に対する書式設定ファセット 

numeric_limits

スカラー型に関する情報を表すためのクラス 

numpunct

数値句読文字ファセット 

numpunct_byname

数値句読文字ファセット 

ofstream

1 つのファイル記述子に関連付けられた、複数の指定ファイルまたはその他デバイスへの書き込みをサポートする 

ostream

ストリームバッファーが制御するシーケンスに対する出力の書式設定と書き込みをサポートする 

ostream_iterator

ostream と istream に反復子を使用可能にするストリーム反復子 

ostreambuf_iterator

作成元のストリームバッファーに連続する文字を書き込む 

ostringstream

basic_string<charT,traits,Allocator> クラスのオブジェクトの書き込みをサポートする

ostrstream

メモリー上の配列に書き込みを行う 

pair

異種の値の組み合わせ用テンプレート 

partial_sort

エンティティーのコレクションをソートするためのテンプレート化されたアルゴリズム 

partial_sort_copy

エンティティーのコレクションをソートするためのテンプレート化されたアルゴリズム 

partial_sum

ある範囲の値の連続した部分小計を求める 

partition

指定述語を満たす全エンティティーを、満たさない全エンティティーの前に書き込む 

permutation

並べ替え関数に基づいてシーケンスの内容を連続的に入れ替えたものを生成する 

plus

1 つ目と 2 つ目の引数を加算した結果を返す 2 項関数オブジェクト 

pointer_to_binary_function

binary_function の代わりとしてポインタを 2 項関数に適用する関数オブジェクト

pointer_to_unary_function

unary_function の代わりとしてポインタを関数に適用する関数オブジェクトクラス

pop_heap

ヒープの外に最大要素を移動する 

prev_permutation

並べ替え関数に基づいてシーケンスの内容を連続的に入れ替えたものを生成する 

priority_queue

優先順位付きの待ち行列のように振る舞うコンテナアダプタ 

ptr_fun

関数の代わりとしてポインタを関数に適用するときに多重定義される関数 

push_heap

ヒープに新しい要素を書き込む 

queue

先入れ先出しの待ち行列のように振る舞うコンテナアダプタ 

random_shuffle

コレクションの要素を無作為にシャッフルする 

raw_storage_iterator

反復子ベースのアルゴリズムが初期化されていないメモリーに結果を書き込めるようにする 

remove

目的の要素をコンテナの先頭に移動し、目的の要素シーケンスの終了位置を表す反復子を返す 

remove_copy

目的の要素をコンテナの先頭に移動し、目的の要素シーケンスの終了位置を表す反復子を返す 

remove_copy_if

目的の要素をコンテナの先頭に移動し、目的の要素シーケンスの終了位置を表す反復子を返す 

remove_if

目的の要素をコンテナの先頭に移動し、目的の要素シーケンスの終了位置を表す反復子を返す 

replace

コレクション内の要素の値を置換する 

replace_copy

コレクション内の要素の値を置換して、置換後のシーケンスを結果に移動する 

replace_copy_if

コレクション内の要素の値を置換して、置換後のシーケンスを結果に移動する 

replace_if

コレクション内の要素の値を置換する 

return_temporary_buffer

メモリーを処理するためのポインタベースのプリミティブ 

reverse

コレクション内の要素を逆順にする 

reverse_copy

コレクション内の要素を逆順にしながら、その結果を新しいコレクションにコピーする 

reverse_iterator

コレクションを逆方向にたどる反復子 

rotate

先頭から中央直前の要素までのセグメントと中央から末尾までの要素のセグメントを交換する 

rotate_copy

先頭から中央直前の要素までのセグメントと中央から末尾までの要素のセグメントを交換する 

search

値シーケンスから、要素単位で指定範囲の値に等しいサブシーケンスを検出する 

search_n

値シーケンスから、要素単位で指定範囲の値に等しいサブシーケンスを検出する 

set

一意のキーを扱う連想コンテナ 

set_difference

ソートされた差を作成する基本的な集合演算 

set_intersection

ソートされた積集合を作成する基本的な集合演算 

set_symmetric_difference

ソートされた対称差を作成する基本的な集合演算 

set_union

ソートされた和集合を作成する基本的な集合演算 

slice

配列の BLAS に似たスライスを表す数値配列クラス 

slice_array

valarray の BLAS に似たスライスを表す数値配列クラス

smanip

パラメータ化されたマニピュレータを実装するときに使用する補助クラス 

smanip_fill

パラメータ化されたマニピュレータを実装するときに使用する補助クラス 

sort

エンティティーのコレクションをソートするためのテンプレート化されたアルゴリズム 

sort_heap

ヒープをソートされたコレクションに変換する 

stable_partition

各グループ内の要素の相対的な順序を保持しながら、指定判定子を満たす全エンティティーを満たさない全エンティティーの前に書き込む 

stable_sort

エンティティーのコレクションをソートするためのテンプレート化されたアルゴリズム 

stack

先入れ先出しのスタックのように振る舞うコンテナアダプタ 

streambuf

各種のストリームバッファーを派生させて、 文字シーケンスを制御しやすいようにする抽象基底クラス 

string

basic_string<charchar_traits<char>allocator<char>> 用の型定義

stringbuf

入力または出力シーケンスを任意の文字シーケンスに関連付ける 

stringstream

メモリー上の配列に対する basic_string<charT,traits,Alocator> クラスのオブジェクトの書き込みおよび読み取りをサポートする

strstream

メモリー上の配列に対する読み取りと書き込みを行う 

strstreambuf

入力または出力シーケンスを、要素が任意の値を格納する超小型の文字配列に関連付ける 

swap

値を交換する 

swap_ranges

ある位置の値の範囲を別の位置の値と交換する 

time_get

入力に対する時刻書式設定ファセット 

time_get_byname

指定ロケールに基づいた、入力に対する時刻書式設定ファセット 

time_put

入力に対する時刻書式設定ファセット 

time_put_byname

指定ロケールに基づいた、入力に対する時刻書式設定ファセット 

tolower

文字を小文字に変換する 

toupper

文字を大文字に変換する 

transform

コレクション内の値の範囲に演算を適用し、 結果を格納する 

unary_function

単項関数オブジェクトを作成するための基底クラス 

unary_negate

単項述語の結果の補数を返す関数オブジェクト 

uninitialized_copy

構造構文を使用してある範囲の値を別の位置にコピーするアルゴリズム 

uninitialized_fill

コレクション内の値の設定に構造構文アルゴリズムを使用するアルゴリズム 

uninitialized_fill_n

コレクション内の値の設定に構造構文アルゴリズムを使用するアルゴリズム 

unique

1 つの範囲の値から連続する重複値を削除し、 得られた一意の値を結果に書き込む 

unique_copy

1 つの範囲の値から連続する重複値を削除し、 得られた一意の値を結果に書き込む 

upper_bound

ソートされたコンテナ内の最後に有効な値位置を求める 

use_facet

ファセットの取得に使用するテンプレート関数 

valarray

数値演算用に最適化された配列クラス 

vector

ランダムアクセス反復子をサポートするシーケンス 

wcerr

<cstdio> で宣言されたオブジェクトの stderr に関連付けられたバッファリングなしストリームバッファーに対する出力を制御する

wcin

<cstdio> で宣言されたオブジェクトの stdin に関連付けられたストリームバッファーからの入力を制御する

wclog

<cstdio> で宣言されたオブジェクトの stderr に関連付けられたストリームバッファーに対する出力を制御する

wcout

<cstdio> で宣言されたオブジェクトの stderr に関連付けられたストリームバッファーに対する出力を制御する

wfilebuf

入力または出力シーケンスをファイルに関連付ける 

wfstream

1 つのファイル記述子に関連付けられた、複数の指定ファイルまたはその他デバイスに対する読み書きをサポートする 

wifstream

1 つのファイル記述子に関連付けられた、複数の指定ファイルまたはその他デバイスからの読み取りをサポートする 

wios

すべてのストリームが共通に必要とする関数を取り込む基底クラス 

wistream

ストリームバッファーが制御する文字シーケンスからの入力の読み取りと解釈をサポートする 

wistringstream

メモリー上の配列からの basic_string<charT,traits,Allocator> クラスのオブジェクトの読み取りをサポートする

wofstream

1 つのファイル記述子に関連付けられた、複数の指定ファイルまたはその他デバイスへの書き込みをサポートする 

wostream

ストリームバッファーが制御するシーケンスに対する出力の書式設定と書き込みをサポートする 

wostringstream

basic_string<charT,traits,Allocator> クラスのオブジェクトの書き込みをサポートする

wstreambuf

各種のストリームバッファーを派生させて、 文字シーケンスを制御しやすいようにする抽象基底クラス 

wstring

basic_string<wchar_tchar_traits<wchar_t>allocator<wchar_t>> 用の型定義

wstringbuf

入力または出力シーケンスを任意の文字シーケンスに関連付ける 

13.3 STLport

libCstd の代替ライブラリを使用する場合は、標準ライブラリの STLport 実装を使用します。 libCstd をオフにして、STLport ライブラリで代用するには、次のコンパイラオプションを使用します。

詳細は、「A.2.49 -library=l[ ,l...]」を参照してください。

このリリースでは、libstlport.a という静的アーカイブおよび libstlport.so という動的ライブラリの両方が含まれています。

STLport 実装を使用するかどうかは、次のことを考慮して判断してください。

13.3.1 再配布とサポートされる STLport ライブラリ

エンドユーザーオブジェクトコードライセンスの条件に基づいて、作成した実行可能ファイルまたはライブラリとともに再配布可能なライブラリおよびオブジェクトファイルの一覧は、実行時ライブラリの README を参照してください。 この README の C++ セクションに、このリリースのコンパイラがサポートしている STLport .so のバージョンが記載されています。この README は、インストールされている製品に付属しています。HTML 版を表示するには、デフォルトのインストールディレクトリにある次のファイルを開きます。

     file:/opt/SUNWspro/docs/index.html

注 –

製品のソフトウェアが /opt ディレクトリにインストールされていない場合は、ご使用のシステムでの実際のパスをシステム管理者に確認してください。


次の例は、ライブラリの実装について移植性のない想定が行われているため、STLport を使用してコンパイルできません。特に、<vector> または <iostream><iterator> を自動的にインクルードすることを想定していますが、これは正しい想定ではありません。


#include <vector>
#include <iostream>

using namespace std;

int main ()
{
    vector <int> v1 (10);
    vector <int> v3 (v1.size());
    for (int i = 0; i < v1.size (); i++)
      {v1[i] = i; v3[i] = i;}
    vector <int> v2(v1.size ());
    copy_backward (v1.begin (), v1.end (), v2.end ());
    ostream_iterator<int> iter (cout, " ");
    copy (v2.begin (), v2.end (), iter);
    cout << endl;
    return 0;
}

問題を解決するには、ソースで <iterator> をインクルードします。

第 14 章 従来の iostream ライブラリの使用

C++ も C と同様に組み込み型の入出力文はありません。その代わりに、出力機能はライブラリで提供されています。C++ コンパイラでは iostream クラスに対して、従来型の実装と ISO 標準の実装を両方とも 提供しています。

この章では、従来型の iostream ライブラリの概要と使用例を説明します。この章では、iostream ライブラリを完全に説明しているわけではありません。詳細は、iostream ライブラリのマニュアルページを参照してください。従来型の iostream のマニュアルページを表示するには、次のように入力します (name にはマニュアルページのトピック名を入力)。man -s 3CC4 name

14.1 定義済みの iostream

定義済みの iostream には、次のものがあります。

定義済み iostream は、cerr を除いて完全にバッファリングされています。「14.3.1 iostream を使用した出力」「14.3.2 iostream を使用した入力」を参照してください。

14.2 iostream 操作の基本構造

iostream ライブラリを使用すると、プログラムで必要な数の入出力ストリームを使用できます。それぞれのストリームは、次のどれかを入力先または出力先とします。

ストリームは、入力のみまたは出力のみと制限して使用することも、入出力両方に使用することもできます。iostream ライブラリでは、次の 2 つの処理階層を使用してこのようなストリームを実現しています。

標準入力、標準出力、標準エラーは、istream または ostream から派生した特殊なクラスオブジェクトで処理されます。

ifstreamofstreamfstream の 3 つのクラスはそれぞれ istreamostreamiostream から派生しており、ファイルへの入出力を処理します。

istrstreamostrstreamstrstream の 3 つのクラスはそれぞれ istreamostream、および iostream から派生しており、文字型配列への入出力を処理します。

入力ストリームまたは出力ストリームをオープンする場合は、どれかの型のオブジェクトを生成し、そのストリームのメンバー streambuf をデバイスまたはファイルに関連付けます。通常、関連付けはストリームコンストラクタで行うので 、ユーザーが直接 streambuf を操作することはありません。標準入力、標準出力、エラー出力に対しては、iostream ライブラリであらかじめストリームオブジェクトを定義してあるので、これらのストリームについてはユーザーが独自にオブジェクトを生成する必要はありません。

ストリームへのデータの挿入 (出力)、ストリームからのデータの抽出 (入力)、挿入または抽出したデータのフォーマット制御には、演算子または iostream のメンバー関数を使用します。

新たなデータ型 (ユーザー定義のクラス) を挿入したり抽出したりするときは一般に、挿入演算子と抽出演算子の多重定義をユーザーが行います。

14.3 従来の iostream ライブラリの使用

従来型の iostream ライブラリルーチンを使用するには、ライブラリの使用部分に対応するヘッダーファイルをインクルードする必要があります。 次の表で各ヘッダーファイルについて説明します。

表 14–1 iostream ルーチンのヘッダーファイル

ヘッダーファイル 

内容の説明 

iostream.h

iostream ライブラリの基本機能の宣言。

fstream.h

ファイルに固有の iostreamstreambuf の宣言。この中で iostream.h をインクルードします。

strstream.h

文字型配列に固有の iostreamstreambuf の宣言。この中で iostream.h をインクルードします。

iomanip.h

マニピュレータ値の宣言。マニピュレータ値とは iostream に挿入または iostream から抽出する値で、特別の効果を引き起こします。この中で iostream.h をインクルードします。

stdiostream.h

(旧形式) 標準入出力の FILE 使用のための iostreamstreambuf の宣言。この中で iostream.h をインクルードします。

stream.h

(旧形式) この中で iostream.hfstream.hiomanip.hstdiostream.h をインクルードします。C++ version 1.2 の旧形式ストリームと互換性を保つための宣言。

これらのヘッダーファイルすべてをプログラムにインクルードする必要はありません。自分のプログラムで必要な宣言の入ったものだけをインクルードします。互換モード (-compat[=4]) では、従来型の iostream ライブラリは lib C の一部であり、CC ドライバによって自動的にリンクされます。標準モード (デフォルトのモード) では、従来型の libiostream ライブラリは iostream に含まれています。

14.3.1 iostream を使用した出力

iostream を使用した出力は、通常、左シフト演算子 (<<) を多重定義したもの (iostream の文脈では 挿入演算子といいます) を使用します。 ある値を標準出力に出力するには、その値を定義済みの出力ストリーム cout に挿入します。たとえば someValue を出力するには、次の文を標準出力に挿入します。


cout << someValue;

挿入演算子は、すべての組み込み型について多重定義されており、someValue の値は適当な出力形式に変換されます。たとえば someValuefloat 型の場合 << 演算子はその値を数字と小数点の組み合わせに変換します。float 型の値を出力ストリームに挿入するときは、<< を float 型挿入子といいます。一般に X 型の値を出力ストリームに挿入するときは、<<X 型挿入子といいます。出力形式とその制御方法については、ios(3CC4) のマニュアルページを参照してください。

iostream ライブラリでは、ユーザー定義型については検知しません。したがってユーザー定義型を出力する場合は、ユーザーが自分で挿入子を正しく定義する、すなわち << 演算子を多重定義する必要があります。

<< 演算子は反復使用できます。2 つの値を cout に挿入するには、次の例のような文を使用できます。


cout << someValue << anotherValue;

前述の例では、2 つの値の間に空白が入りません。空白を入れる場合は、次のようにします。


cout << someValue << " " << anotherValue;

<< 演算子は、組み込みの左シフト演算子と同じ優先順位を持ちます。ほかの演算子と同様に、括弧を使用して実行順序を指定できます。 実行順序をはっきりさせるためにも、括弧を使用するとよい場合がよくあります。次の 4 つの文のうち、最初の 2 つは同じ結果になりますが、あとの 2 つは異なります。


cout << a+b;              // + は << より優先順位が高い
cout << (a+b);
cout << (a&y);            // << は & より優先順位が高い
cout << a&y;            // (cout << a) & y となっておそらくエラーになる

14.3.1.1 ユーザー定義の挿入演算子

次のコーディング例では string クラスを定義しています。


#include <stdlib.h>
#include <iostream.h>


class string {
private:
    char* data;
    size_t size;

public:
    // (さまざまな関数定義)

    friend ostream& operator<<(ostream&, const string&);
    friend istream& operator>>(istream&, string&);
};

この例では、挿入演算子と抽出演算子をフレンド定義しておく必要があります。string クラスのデータ部が非公開だからです。


ostream& operator<< (ostream& ostr, const string& output)
{    return ostr << output.data;}

前述の定義は、string クラスに対して多重定義された演算子関数 operator<< の定義です。


cout << string1 << string2;

operator<< は、最初の引数として ostream& (ostream への参照) を受け取り、同じ ostream を返します。このため、次のように 1 つの文で挿入演算子を続けて使用できます。

14.3.1.2 出力エラーの処理

operator<< を多重定義するときは、iostream ライブラリからエラーが通知されることになるため、特にエラー検査を行う必要はありません。

エラーが起こると、エラーの起こった iostreamエラー状態になります。その iostream の状態の各ビットが、エラーの大きな分類に従ってセットされます。iostream で定義された挿入子がストリームにデータを挿入しようとしても、そのストリームがエラー状態の場合はデータが挿入されず、そのストリームの状態も変わりません。

一般的なエラー処理方法は、メインのどこかで定期的に出力ストリームの状態を検査する方法です。そこで、エラーが起こっていることがわかれば、何らかの処理を行います。この章では、文字列を出力してプログラムを中止させる関数 error をユーザーが定義しているものとして説明します。関数 error はユーザー定義の関数で、定義済みの関数ではありません。関数 error の内容については、「14.3.9 入力エラーの処理」を参照してください。iostream の状態を調べるには、演算子 ! を使用 します。iostream がエラー状態の場合はゼロ以外の値を返します。次に例を示します。


if (!cout) error("output error");

エラーを調べるにはもう 1 つの方法があります。ios クラスでは、operator void *() が定義されており、エラーが起こった場合は NULL ポインタを返します。したがって、次の文でエラーを検査できます。


if (cout << x) return; // 正常終了のときのみ返す

また、次のように ios クラスのメンバー関数 good を使用することもできます。


if (cout.good()) return; // 正常終了のときのみ返す

エラービットは次のような列挙型で宣言されています。


enum io_state {goodbit=0, eofbit=1, failbit=2,
badbit=4, hardfail=0x80};

エラー関数の詳細については、iostream のマニュアルページを参照してください。

14.3.1.3 出力のフラッシュ

多くの入出力ライブラリと同様、iostream も出力データを蓄積し、より大きなブロックにまとめて効率よく出力します。出力バッファーをフラッシュする場合、次のように特殊な値 flush を挿入するだけでフラッシュできます。次に例を示します。


cout << "This needs to get out immediately." << flush;
 

flush は、マニピュレータと呼ばれるタイプのオブジェクトの 1 つです。マニピュレータを iostream に挿入すると、その値が出力されるのではなく、何らかの効果が引き起こされます。マニピュレータは実際には関数で、ostream& または istream& を引数として受け取り、そのストリームに対する何らかの動作を実行したあとにその引数を返します。「14.7 マニピュレータ」を参照してください。

14.3.1.4 バイナリ出力

ある値をバイナリ形式のままで出力するには、次の例のようにメンバー関数 write を使用します。次の例では、x の値がバイナリ形式のまま出力されます。


cout.write((char*)&x, sizeof(x));

この例では、&xchar* に変換しており、型変換の規則に反します。通常このようにしても問題はありませんが、x の型が、ポインタ、仮想メンバー関数、またはコンストラクタの重要な動作を要求するものを持つクラスの場合、前述の例で出力した値を正しく読み込むことができません。

14.3.2 iostream を使用した入力

iostream を使用した入力は、iostream を使用した出力と同じです。入力には、抽出 演算子 >> を使用します。挿入演算子と同様に繰り返し指定できます。次に例を示します。


cin >> a >> b;

この例では、標準入力から 2 つの値が取り出されます。ほかの多重定義演算子と同様に、使用される抽出子の機能は ab の型によって決まります。ab の型が異なれば、別の抽出子が使用されます。入力データのフォーマットとその制御方法についての詳細は、ios(3CC4) のマニュアルページを参照してください。通常は、先頭の空白文字 (スペース、改行、タブ、フォームフィードなど) は無視されます。

14.3.3 ユーザー定義の抽出演算子

ユーザーが新たに定義した型のデータを入力するには、出力のために挿入演算子を多重定義したのと同様に、その型に対する抽出演算子を多重定義します。

クラス string の抽出演算子は次のコーディング例のように定義します。


例 14–1 string の抽出演算子


istream& operator>> (istream& istr, string& input)
{
    const int maxline = 256;
    char holder[maxline];
    istr.get(holder, maxline, ”\n’);
    input = holder;
    return istr;
}

get 関数は、入力ストリーム istr から文字列を読み取ります。 読み取られた文字列は、maxline-1 バイトの文字が読み込まれる、新しい行に達する、EOF に達する、のうちのいずれかが発生するまで、holder に格納されます。データ holder は NULL で終わります。最後に、holder 内の文字列がターゲットの文字列にコピーされます。

規則に従って、抽出子は第 1 引数 (前述の例では istream& istr) から取り出した文字列を変換し、常に参照引数である第 2 引数に格納し、第 1 引数を返します。抽出子とは、入力値を第 2 引数に格納するためのものなので、第 2 引数は必ず参照引数である必要があります。

14.3.4 char* の抽出子

この定義済み抽出子は問題が起こる可能性があるため、ここで説明しておきます。この抽出子は次のように使用します。


char x[50];
cin >> x;

前述の例で、抽出子は先頭の空白を読み飛ばし、次の空白文字までの文字列を抽出して x にコピーします。次に、文字列の最後を示す NULL 文字 (0) を入れて文字列を完成します。ここで、入力文字列が指定した配列からあふれる可能性があることに注意してください。

さらに、ポインタが、割り当てられた記憶領域を指していることを確認する必要があります。次に示すのは、よく発生するエラーの例です。


char * p; // 初期化されていない
cin >> p;

入力データが格納される場所が特定されていません。 これによって、プログラムが異常終了することがあります。

14.3.5 1 文字の読み込み

char 型の抽出子を使用することに加えて、次に示すいずれかの形式でメンバー関数 get を使用することによって、1 文字を読み取ることができます。次に例を示します。


char c;
cin.get(c); // 入力に失敗した場合は、c は変更なし

int b;
b = cin.get(); // 入力に失敗した場合は、b を EOF に設定

注 –

ほかの抽出子とは異なり、char 型の抽出子は行頭の空白を読み飛ばしません


空白だけを読み飛ばして、タブや改行などそのほかの文字を取り出すようにするには、次のようにします。


int a;
do {
    a = cin.get();
   }
while(a ==’ ’);

14.3.6 バイナリ入力

メンバー関数 write で出力したようなバイナリの値を読み込むには、メンバー関数 read を使用します。次の例では、メンバー関数 read を使用して x のバイナリ形式の値をそのまま入力します。 次の例は、先に示した関数 write を使用した例と反対のことを行います。


cin.read((char*)&x, sizeof(x));

14.3.7 入力データの先読み

メンバー関数 peek を使用するとストリームから次の文字を抽出することなく、その文字を知ることができます。次に例を示します。


if (cin.peek()!= c) return 0;

14.3.8 空白の抽出

デフォルトでは、iostream の抽出子は先頭の空白を読み飛ばします。 skip フラグをオフにすれば、先頭の空白を読み飛ばさないようにできます。次の例では、 cin の先頭の空白の読み飛ばしをいったんオフにし、のちにオンに戻しています。


cin.unsetf(ios::skipws); // 先頭の空白の読み飛ばしをオフに設定
...
cin.setf(ios::skipws); // 先頭の空白の読み飛ばしをオフに設定

iostream のマニピュレータ ws を使用すると、空白の読み飛ばしが現在オンかオフかに関係なく、iostream から先頭の空白を取り除くことができます。次の例では、iostream istr から先頭の空白が取り除かれます。


istr >> ws;

14.3.9 入力エラーの処理

通常は、第 1 引数が非ゼロのエラー状態にある場合、抽出子は入力ストリームからのデータの抽出とエラービットのクリアを行わないでください。データの抽出に失敗した場合、抽出子は最低 1 つのエラービットを設定します。

出力エラーの場合と同様、エラー状態を定期的に検査し、非ゼロの状態の場合は処理の中止など何らかの動作を起こす必要があります。演算子 ! は、iostream のエラー状態を検査します。たとえば次のコーディング例では、英字を入力すると入力エラーが発生します。


#include <stdlib.h>
#include <iostream.h>
void error (const char* message) {
     cerr << message << "\n";
     exit(1);
}
int main() {
     cout << "Enter some characters: ";
     int bad;
     cin >> bad;
     if (!cin) error("aborted due to input error");
     cout << "If you see this, not an error." << "\n";
     return 0;
}

クラス ios には、エラー処理に使用できるメンバー関数があります。詳細はマニュアルページを参照してください。

14.3.10 iostreamstdio の併用

C++ でも stdio を使用できますが、プログラムで iostreamstdio とを標準ストリームとして併用すると、問題が起こる場合があります。たとえば stdoutcout の両方に書き込んだ場合、個別にバッファリングされるため出力結果が設計したとおりにならないことがあります。stdincin の両方から入力した場合、問題はさらに深刻です。 個別にバッファリングされるため、入力データが使用できなくなってしまいます。

標準入力、標準出力、標準エラーに関するこのような問題を解決するためには、入出力に先立って次の命令を実行します。次の命令で、すべての定義済み iostream が、それぞれ対応する定義済みの標準入出力の FILE に結合されます。


ios::sync_with_stdio();

このような結合を行うと、定義済みストリームが結合されたものの一部となってバッファリングされなくなってかなり効率が悪くなるため、デフォルトでは結合されていません。同じプログラムでも、stdioiostream を別のファイルに対して使用することはできます。すなわち、stdio ルーチンを使用して stdout に書き込み、iostream に結合した別のファイルに書き込むことは可能です。また stdio FILE を入力用にオープンしても、stdin から入力しないかぎりは cin からも読み込むことができます。

14.4 iostream の作成

定義済みの iostream 以外のストリームへの入出力を行う場合は、ユーザーが自分で iostream を生成する必要があります。これは一般には、iostream ライブラリで定義されている型のオブジェクトを生成することになります。ここでは、使用できるさまざまな型について説明します。

14.4.1 クラス fstream を使用したファイル操作

ファイル操作は標準入出力の操作に似ています。ifstreamofstrea mfstream の 3 つのクラスはそれぞれ、istreamostreamiostream の各クラスから派生しています。この 3 つのクラスは派生クラスなので、挿入演算と抽出演算、および、そのほかのメンバー関数を継承しており、ファイル使用のためのメンバーとコンストラクタも持っています。

fstream のいずれかを使用するときは、fstream.h をインクルードします。入力だけ行うときは ifstream、出力だけ行うときは ofstream、入出力を行うときは fstream を使用します。コンストラクタへの引数としてはファイル名を渡します。

thisFile というファイルから thatFile というファイルへのファイルコピーを行うときは、次のコーディング例のようになります。


ifstream fromFile("thisFile");
if     (!fromFile)
    error("unable to open ’thisFile’ for input");
ofstream toFile ("thatFile");
if     (!toFile)
    error("unable to open ’thatFile’ for output");
char c;
while (toFile && fromFile.get(c)) toFile.put(c);

このコードでは次のことを実行します。

14.4.1.1 オープンモード

オープンモードは、列挙型 open_mode の各ビットの OR をとって設定します。open_mode は、ios クラスの公開部で次のように定義されています。


enum open_mode {binary=0, in=1, out=2, ate=4, app=8, trunc=0x10,
     nocreate=0x20, noreplace=0x40};

注 –

UNIX では binary フラグは必要ありませんが、binary フラグを必要とするシステムとの互換性を保つために提供されています。移植可能なコードにするためには、バイナリファイルをオープンするときに binary フラグを使用する必要があります。


入出力両用のファイルをオープンできます。たとえば次のコードでは、 someName という入出力ファイルをオープンして、fstream 変数 inoutFile に結合します。


fstream inoutFile("someName", ios::in|ios::out);

14.4.1.2 ファイルを指定しない fstream の宣言

ファイルを指定せずに fstream の宣言だけを行い、のちにファイルをオープンすることもできます。次の例では出力用の ofstream toFile を作成します。


ofstream toFile;
toFile.open(argv[1], ios::out);

14.4.1.3 ファイルのオープンとクローズ

fstream をいったんクローズし、また別のファイルでオープンすることができます。たとえば、コマンド行で与えられるファイルリストを処理するには次のようにします。


ifstream infile;
for (char** f = &argv[1]; *f; ++f) {
   infile.open(*f, ios::in);
   ...;
   infile.close();
}

14.4.1.4 ファイル記述子を使用したファイルのオープン

標準出力は整数 1 などのようにファイル記述子がわかっている場合は、次のようにファイルをオープンできます。


ofstream outfile;
outfile.attach(1);

fstream のコンストラクタにファイル名を指定してオープンしたり、open 関数を使用してオープンしたファイルは、fstream が破壊された時点 (delete するか、スコープ外に出る時点) で自動的にクローズされます。attachfstream に結合したファイルは、自動的にはクローズされません。

14.4.1.5 ファイル内の位置の再設定

ファイル内の読み込み位置と書き込み位置を変更することができます。そのためには次のようなツールがあります。


enum seek_dir {beg=0, cur=1, end=2};

fstream aFile の位置再設定の例を次に示します。


streampos original = aFile.tellp();     // 現在の位置の保存
aFile.seekp(0, ios::end); // ファイルの最後に位置を再設定
aFile << x;               // データをファイルに書き込む
aFile.seekp(original);    // 元の位置に戻る

seekg (seekp) は、1 つまたは 2 つの引数を受け取ります。引数を 2 つ受け取るときは、第 1 引数は、第 2 引数で指定した seek_dir 値が示す位置からの相対位置となります。次に例を示します。


aFile.seekp(-10, ios::end);

この例では、ファイルの最後から 10 バイトの位置に設定されます。


aFile.seekp(10, ios::cur);

一方、次の例では現在位置から 10 バイト進められます。


注 –

テキストストリーム上での任意位置へのシーク動作はマシン依存になります。 ただし、以前に保存した streampos の値にいつでも戻ることができます。


14.5 iostream の代入

iostream では、あるストリームを別のストリームに代入することはできません。

ストリームオブジェクトをコピーすると、出力ファイル内の現在の書き込み位置ポインタなどの位置情報が二重に存在するようになり、それを個別に変更できるという状態が起こります。これは、ストリーム操作を混乱させる可能性があります。

14.6 フォーマットの制御

フォーマットの制御については、ios(3CC4) のマニュアルページで詳しく説明しています。

14.7 マニピュレータ

マニピュレータとは、iostream に挿入したり、iostream から抽出したりする値で特別な効果を持つもののことです。

引数付きマニピュレータとは、 1 つ以上の追加の引数を持つマニピュレータのことです。

マニピュレータは通常の識別子であるため、マニピュレータの定義を多く行うと可能な名前を使いきってしまうので、iostream では考えられるすべての機能に対して定義されているわけではありません。マニピュレータの多くは、この章の別の箇所でメンバー関数とともに説明しています。

定義済みマニピュレータは 13 個あり、それぞれについては表 14–2 で説明します。この表で使用している文字の意味は次のとおりです。

表 14–2 iostream の定義済みマニピュレータ

 

定義済みマニピュレータ 

内容の説明 


ostr << dec, istr >> dec

基数が 10 の整数変換を指定します。 


ostr << endl

復帰改行文字 ('\n') を挿入して、ostream::flush() を呼び出します。


ostr << ends

NULL ( 0 ) 文字を挿入。strstream 使用時に利用します。


ostr << flush

ostream::flush() を呼び出します。


ostr << hex, istr >> hex

基数が 16 の整数変換を指定します。 


ostr << oct, istr >> oct

基数が 8 の整数変換を指定します。 


istr >> ws

最初に空白以外の文字が見つかるまで (この文字以降は istr に残る)、空白を取り除きます (空白を読み飛ばす)。


ostr << setbase(n),  istr >>
setbase(n)

基数が n (0, 8, 10, 16 のみ) の整数変換を指定します。


ostr << setw(n), istr  >> setw(n)

ios::width(n) を呼び出します。フィールド幅を n に設定します。

10 


ostr << resetiosflags(i), istr>>
resetiosflags(i)

i のビットセットに従って、フラグのビットベクトルをクリアします。

11 


ostr << setiosflags(i), istr >>
setiosflags(i)

i のビットセットに従って、フラグのビットベクトルを設定します。

12 


ostr << setfill(c), istr >>
setfill(c)

埋め込み文字 (フィールドのパディング用文字) を c とします。

13 


ostr << setprecision(n), istr
>>setprecision(n)

浮動小数点型データの精度を n 桁にします。

定義済みマニピュレータを使用するには、プログラムにヘッダーファイル iomanip.h をインクルードする必要があります。

ユーザーが独自のマニピュレータを定義することもできます。マニピュレータには次の 2 つの基本タイプがあります。

14.7.1 引数なしのマニピュレータの使用法

引数なしのマニピュレータは、次の 3 つを実行する関数です。

iostream では、このような関数 (へのポインタ) を使用するシフト演算子がすでに定義されていますので、関数を入出力演算子シーケンスの中に入れることができます。シフト演算子は、値の入出力を行う代わりに、その関数を呼び出します。tabostream に挿入する tab マニピュレータの例を示します。


ostream& tab(ostream& os) {
             return os <<’\t’;
            }
...
cout << x << tab << y;

次のコードは、前述の例と同じ処理をより洗練された方法で行います。


const char tab = ’\t’;
...
cout << x << tab << y;

次に示すのは別の例で、定数を使用してこれと同じことを簡単に実行することはできません。入力ストリームに対して、空白の読み飛ばしのオン、オフを設定すると仮定します。ios::setfios::unsetf を別々に呼び出して、skipws フラグをオンまたはオフに設定することもできますが、次の例のように 2 つのマニピュレータを定義して設定することもできます。


#include <iostream.h>
#include <iomanip.h>
istream& skipon(istream &is) {
       is.setf(ios::skipws, ios::skipws);
       return is;
}
istream& skipoff(istream& is) {
       is.unsetf(ios::skipws);
       return is;
}
...
int main ()
{
      int x,y;
      cin >> skipon >> x >> skipoff >> y;
      return 1;
}

14.7.2 引数付きのマニピュレータの使用法

iomanip.h に入っているマニピュレータの 1 つに setfill があります。setfill は、フィールド幅に詰め合わせる文字を設定するマニピュレータで、次の例に示すように定義されています。


// ファイル setfill.cc
#include<iostream.h>
#include<iomanip.h>

// 非公開のマニピュレータ
static ios& sfill(ios& i, int f) {
         i.fill(f);
         return i;
}
// 公開の適用子
smanip_int setfill(int f) {
       return smanip_int(sfill, f);
}

引数付きマニピュレータは、2 つの部分から構成されます。

ヘッダーファイル iomanip.h には、さまざまなクラスが定義されています。各クラスには、マニピュレータ関数のアドレスと 1 つの引数の値が入っています。iomanip クラスについては、manip(3CC4) のマニュアルページで説明しています。 この前の例では、smanip_int クラスを使用しており、ios で使用できます。ios で使用できるということは、istreamostream でも使用できるということです。この例ではまた、int 型の第 2 引数を使用しています。

適用子は、クラスオブジェクトを作成してそれを返します。この前の例では、smanip_int というクラスオブジェクトが作成され、そこにマニピュレータと、適用子の int 型引数が入っています。ヘッダーファイル iomanip.h では、このクラスに対するシフト演算子が定義されています。入出力演算子シーケンスの中に適用子関数 setfill があると、その適用子関数が呼び出され、クラスが返されます。シフト演算子はそのクラスに対して働き、クラス内に入っている引数値 を使用してマニピュレータ関数が呼び出されます。

次の例では、マニピュレータ print_hex は次のことを行います。

この例は出力専用のため、omanip_long クラスが使用されています。 また、int 型でなく long 型でデータを操作します。


#include <iostream.h>
#include <iomanip.h>
static ostream& xfield(ostream& os, long v) {
        long save = os.setf(ios::hex, ios::basefield);
        os << v;
        os.setf(save, ios::basefield);
        return os;
    }
omanip_long print_hex(long v) {
       return omanip_long(xfield, v);
   }

14.8 strstream: 配列用の iostreams

strstream(3CC4) のマニュアルページを参照してください。

14.9 Stdiobufs: 標準入出力ファイル用の iostream

stdiobuf(3CC4) のマニュアルページを参照してください。

14.10 streambuf

入力や出力のシステムは、フォーマットを行う iostream と、フォーマットなしの文字ストリームの入力または出力を行う streambuf からなります。

通常は iostream を通して streambuf を使用するので、 streambuf の詳細を知る必要はありません。ただし、効率をよくするため、または iostream に組み込まれているエラー処理やフォーマットのためなどに必要な場合は、直接 streambuf を使用できます。

14.10.1 streambuf の機能

streambuf は文字シーケンス (文字ストリーム) と、シーケンス内を指す 1 つまたは 2 つのポインタとで構成されています。各ポインタは文字と文字の間を指しています。実際には文字と文字の間を指しているわけではありませんが、このように考えておくと理解しやすくなります。streambuf ポインタには次の種類があります。

streambuf は、このどちらかのポインタ、または両方のポインタを持ちます。

14.10.1.1 ポインタの位置

ポインタ位置の操作とシーケンスの内容の操作にはさまざまな方法があります。文字列の操作時に両方のポインタが移動するかどうかは、使用される streambuf の種類によって違います。一般に、 キュー形式の streambuf の場合は、get ポインタと put ポインタは別々に移動し、ファイル形式の streambuf の場合は、get ポインタと put ポインタは同時に移動します。キュー形式ストリームの例としては strstream があり、ファイル形式ストリームの例としては fstream があります。

14.10.2 streambuf の使用

ユーザーは streambuf オブジェクト自体を作成することはなく、streambuf クラスから派生したクラスのオブジェクトを作成します。その例として、filebufstrstreambuf とがあります。 この 2 つについてはそれぞれ filebuf(3CC4) および ssbuf(3) のマニュアルページを参照してください。より高度な使い方として、独自のクラスを streambuf から派生させて特殊デバイスのインタフェースを提供したり、基本的なバッファリング以外のバッファリングを行なったりすることができます。sbufpub(3CC4) と sbufprot (3CC4) のマニュアルページでは、それらの方法に ついて説明しています。

ユーザー用の特殊な streambuf を作成するとき以外にも、前述のマニュアルページで説明しているように、iostream と結合した streambuf にアクセスして公開メンバー関数を使用したい場合があります。また、各 iostream には、streambuf へのポインタを引数とする定義済みの挿入子と抽出子があります。streambuf を挿入したり抽出したりすると、ストリーム全体がコピーされます。

次の例では、先に説明したファイルコピーとは違う方法でファイルをコピーしています。


ifstream fromFile("thisFile");
ofstream toFile ("thatFile");
toFile << fromFile.rdbuf();

入力ファイルと出力ファイルは、前述の例と同じ方法でオープンします。各 iostream クラスにはメンバー関数 rdbuf があり、それに結合した streambuf オブジェクトへのポインタを返します。fstream の場合、streambuf オブジェクトは filebuf 型です。fromFile に結合したファイル全体が toFile に結合したファイルにコピー (挿入) されます。最後の行は次のように書くこともできます。


fromFile >> toFile.rdbuf();

前述の書き方では、ソースファイルが抽出されて目的のところに入ります。どちらの書き方をしても、結果はまったく同じになります。

14.11 iostream に関するマニュアルページ

C++ では、iostream ライブラリの詳細を説明する多くのマニュアルページがあります。次に、各マニュアルページの概要を示します。

従来型の iostream ライブラリのマニュアルページを表示するには、次のように入力します (name には、マニュアルページのトピック名を入力)。


example% man -s 3CC4 name
表 14–3 iostream に関するマニュアルページの概要

マニュアルページ 

概要 

filebuf

streambuf から派生し、ファイル処理のために特殊化された filebuf クラスの公開インタフェースを詳細に説明します。streambuf クラスから継承した機能の詳細については、sbufpub(3CC4) と sbufprot(3CC4) のマニュアルページを参照してください。filebuf クラスは、fstream クラスを通して使用します。

fstream

istreamostreamiostream をファイル処理用に特殊化した ifstreamofstreamfstream の各クラスの特殊化されたメンバー関数を詳細に説明します。

ios

iostream の基底クラスである ios クラスの各部を詳細に説明します。すべてのストリームに共通の状態データについても説明します。

ios.intro

iostream を紹介し、概要を説明します。

istream

次の各項目を詳細に説明します。 

  • streambuf から取り出した文字の解釈をサポートする、クラス istream のメンバー関数

  • 入力の書式設定

  • ostream の一部として記述されている位置決め関数

  • 一部の関連関数

  • 関連マニピュレータ

manip

iostream ライブラリで定義されている入出力マニピュレータを説明します。

ostream

次の各項目を詳細に説明します。 

  • streambuf から取り出した文字の解釈をサポートする、クラス istream のメンバー関数

  • 出力の書式設定

  • ostream の一部として記述されている位置決め関数

  • 一部の関連関数

  • 関連マニピュレータ

sbufprot

streambuf(3CC4) クラスから派生したクラスをコーディングするプログラマに必要なインタフェースを説明します。公開関数のいくつかは、このマニュアルページでは説明しないため、sbufpub(3CC4) のマニュアルページも参照してください。

sbufpub

streambuf クラスの公開インタフェース、特に streambuf の公開メンバー関数について詳細に説明します。このマニュアルページには、streambuf 型のオブジェクトを直接操作したり、streambuf から派生したクラスが継承している関数を探し出したりするのに必要な情報が含まれています。streambuft からクラスを派生する場合は、sbufprott(3CC4) のマニュアルページも参照してください。

ssbuf

streambuf から派生し、文字型配列処理用に特殊化された strstreambuf クラスの公開インタフェースを詳細に説明します。streambuf クラスから継承する機能の詳細については、sbufpub(3CC4) のマニュアルページを参照してください。

stdiobuf

stdiobuf から派生し、標準入出力の FILE 処理のために特殊化された streambuf クラスについて最小限の説明をします。streambuf クラスから継承する機能の詳細については、sbufpub(3CC4) のマニュアルページを参照してください。

strstream

strstream の特殊化されたメンバー関数を詳細に説明します。 これらの関数は、iostream クラスから派生した一連のクラスで実装され、文字型配列処理用に特殊化されています。

14.12 iostream の用語

iostream ライブラリの説明では、一般のプログラミングに関する用語と同じでも意味が異なる語を多く使用します。次の表では、それらの用語が iostream ライブラリの説明で使用される場合の意味を定義します。

表 14–4 iostream の用語

iostream 用語

定義 

バッファー

バッファーには、2 つの意味があります。 1 つは iostream パッケージに固有のバッファーで、もう 1 つは入出力一般に適用されるバッファーです。

iostream ライブラリに固有のバッファーは、 streambuf クラスで定義されたオブジェクトです。

一般にいうバッファーは、入出力データを効率よく転送するために使用するメモリーブロックを指します。バッファリングされた入出力の場合は、バッファーがいっぱいになるか、バッファーが強制的にフラッシュされるときまで、データの転送は行われません。 

「バッファリングなしのバッファー」とは、前述で定義したように一般にいうバッファーがない streambuf を指します。この章では streambuf を指すバッファーという語を使用しないようにしていますが、マニュアルページやほかの C++ のマニュアルでは、streambuf の意味でバッファーという語を使用しています。

抽出

iostream から入力データを取り出す操作を抽出といいます。

Fstream

ファイル用に特殊化された入出力ストリームです。特に courier のようにクーリエフォントで印刷されている場合は、iostream クラスから派生した fstream クラスを指します。

挿入

iostream に出力データを送り込む操作を挿入といいます。

iostream

一般には、入力ストリームまたは出力ストリームです。 

iostream ライブラリ

ファイル iostream.hfstream.hstrstream.hiomanip.h、ライブラリ stdiostream.h をインクルードすることにより使用できるライブラリです。iostream はオブジェクト指向のライブラリであるため、ユーザーが必要に応じて拡張できます。そのため、iostream ライブラリを使用して実行できるすべての機能があらかじめ定義されているわけではありません。

ストリーム

一般に、iostreamfstreamstrstream、またはユーザー定義のストリームをいいます。

Streambuf

文字シーケンスの入ったバッファーで、put ポインタまたは get ポインタ、あるいはその両方を持ちます。courier のようにクーリエフォントで印刷されている場合は、streambuf という特定のクラスを意味します。そのほかのフォントで印刷されている場合は一般に streambuf クラスのオブジェクト、または streambuf の派生クラスを意味します。ストリームオブジェクトは必ず、streambuf から派生した型のオブジェクト (またはそのオブジェクトへのポインタ) を持っています。

Strstream

文字型配列処理用に特殊化した iostream です。courier のようにクーリエフォントで印刷されている場合は、strstream という特定のクラスを意味します。

第 15 章 複素数演算ライブラリの使用

複素数には「実部」と「虚部」があります。次に例を示します。

3.2 + 4i 1 + 3i 1 + 2.3i

通常は、0 + 3i のように完全に虚部だけのものは通常 3i と書き、5 + 0i のように完全に実部だけのものは通常 5 と書きます。データ型 complex を使用すると複素数を表現できます。


注 –

複素数ライブラリ (libcomplex) は互換モードでのみ使用できます (-compat[=4])。 標準モード (デフォルトのモード) では、同様の機能を持つ複素数クラスが C++ 標準ライブラリ (libCstd) に含まれています。


15.1 複素数ライブラリ

複素数ライブラリは、 新しいデータ型として複素数データ型を実装します。このライブラリには次のものが含まれています。

複素数には、実部と虚部による表現方法のほかに、 絶対値と偏角による表現方法があります。複素数ライブラリには、実部と虚部によるデカルト表現と、絶対値と偏角による極座標表現とを互いに変換する関数も提供しています。

共役複素数は、虚部の符号が反対の複素数です。

15.1.1 複素数ライブラリの使用方法

複素数ライブラリを使用する場合は、プログラムにヘッダーファイル c omplex.h をインクルードし、-lcomplex オプションまたは -library=complex オプションを使用してリンクしてください。

15.2 complex 型

複素数ライブラリでは、クラス complex が 1 つだけ定義されています。クラス complex のオブジェクトは、1 つの複素数を持つことができます。複素数は次の 2 つの部分で構成されています。


class complex {
    double re, im;
};

クラス complex のオブジェクトの値は、1 組の double 型の値です。最初の値が実部を表し、2 番目の値が虚部を表します。

15.2.1 complex クラスのコンストラクタ

complex には 2 つのコンストラクタがあります。それぞれの定義を次に示します。


complex::complex()            {re=0.0; im=0.0;}
complex::complex(double r, double i = 0.0) {re=r; im=i;}

複素数の変数を引数なしで宣言すると、最初のコンストラクタが使用され、実部も虚部もゼロで初期化されます。次の例では、実部も虚部もゼロの複素数の変数が生成されます。


complex aComp;

1 つまたは 2 つのパラメータを指定できます。いずれの場合にも、2 番目のコンストラクタが使用されます。引数を 1 つだけ指定した場合は、その値は実部の値とみなされ虚部はゼロに設定されます。次に例を示します。


complex aComp(4.533);

複素数の値は次のようになります。


4.533 + 0i

引数を 2 つ指定した場合は、最初の値が実部、2 番目の値が虚部となります。次に例を示します。


complex aComp(8.999, 2.333);

複素数の値は次のようになります。


8.999 + 2.333i

また、複素数ライブラリが提供する polar 関数を使用して複素数を生成することもできます。「15.3 数学関数」を参照してください。polar 関数は、指定した 1 組の極座標値 (絶対値と偏角) を使用して複素数を作成します。

complex 型にはデストラクタはありません。

15.2.2 算術演算子

複素数ライブラリでは、すべての基本算術演算子が定義されています。特に、次の 5 つの演算子は通常の型の演算と同様に使用することができ、優先順序も同じです。

+ - / * =

演算子 - は、通常の型の場合と同様に 2 項演算子としても単項演算子としても使用できます。

このほか、次の演算子の使用方法も通常の型で使用する演算子と同様です。

ただし、この 4 つの演算子については、式の中で使用可能な値は生成されません。したがって、次のコードは機能しません。


complex a, b;
...
if ((a+=2)==0) {...}; // 誤り
b = a *= b; // 誤り

また、等しいか否かを判定する 2 つの演算子 (==!=) は、通常の型で使用する演算子と同様に使用することができます。

算術式で実数と複素数が混在しているときは、C++ では複素数のための演算子関数が使用され、実数は複素数に変換されます。

15.3 数学関数

複素数ライブラリには、多くの数学関数が含まれています。複素数に特有のものもあれば、 C の標準数学ライブラリの関数と同じで複素数を対象にしたものもあります。

これらの関数はすべて、あらゆる可能な引数に対して結果を返します。関数が数学的に正しい結果を返せないような場合は、complex_error を呼び出して、何らかの適切な値を返します。たとえば、オーバーフローが実際に起こるのを避けるために complex_error を呼び出してメッセージを出します。次の表で複素数ライブラリの関数を説明します。


注 –

sqrt 関数と atan2 関数は、C99 の csqrt (Annex G) の仕様に従って実装されています。


表 15–1 複素数ライブラリの関数

複素数ライブラリ関数 

内容の説明 

double abs(const complex)

複素数の絶対値を返します。 

double arg(const complex)

複素数の偏角を返します。 

complex conj(const complex)

引数に対する共役複素数を返します。 

double imag(const complex&)

複素数の虚部を返します。 

double norm(const complex)

引数の絶対値の 2 乗を返します。abs より高速ですが、オーバーフローが起きやすくなります。絶対値の比較に使用します。

complex polar(double mag, double ang=0.0)

複素数の絶対値と偏角を表す一組の極座標を引数として受け取り、それに対応する複素数を返します。 

double real(const complex&)

複素数の実部を返します。 

表 15–2 複素数の数学関数と三角関数

複素数ライブラリ関数

内容の説明 

complex acos(const complex)

引数が余弦となるような角度を返します。 

complex asin(const complex)

引数が正弦となるような角度を返します。 

complex atan(const complex)

引数が正接となるような角度を返します。 

complex cos(const complex)

引数の余弦を返します。 

complex cosh(const complex)

引数の双曲線余弦を返します。 

complex exp(const complex)

e**x を計算します。 ここで e は自然対数の底で、 x は関数 exp に渡された引数です。

complex log(const complex)

引数の自然対数を返します。 

complex log10(const complex)

引数の常用対数を返します。 

complex pow(double b, const complex exp)

complex pow(const complex b, int exp)

complex pow(const complex b, double exp)

complex pow(const complex b, const

complex exp)

引数を 2 つ持ちます。pow(b, exp). bexp 乗します。

complex sin(const complex)

引数の正弦を返します。 

complex sinh(const complex)

引数の双曲線正弦を返します。 

complex sqrt(const complex)

引数の平方根を返します。 

complex tan(const complex)

引数の正接を返します。 

complex tanh(const complex)

引数の双曲線正接を返します。 

15.4 エラー処理

複素数ライブラリでは、エラー処理が次のように定義されています。


extern int errno;
class c_exception {...};
int complex_error(c_exception&);

外部変数 errno は C ライブラリの大域的なエラー状態です。errno は、標準ヘッダー errno.h (perror(3) のマニュアルページを参照) にリストされている値を持ちます。errno には、多くの関数でゼロ以外の値が設定されます。

ある特定の演算でエラーが起こったかどうか調べるには、次のようにしてください。

  1. 演算実行前に errno をゼロに設定する。

  2. 演算終了後に値を調べる。

関数 complex_errorc_exception 型の参照引数を持ち、次に示す複素数ライブラリ関数に呼び出されます。

デフォルトの complex_error はゼロを返します。ゼロが返されたということは、デフォルトのエラー処理が実行されたということです。ユーザーは独自の complex_error 関数を作成して、別のエラー処理を行うことができます。エラー処理については、cplxerr(3CC4) のマニュアルページで説明しています。

デフォルトのエラー処理については、cplxtrig(3CC4) と cplxexp(3CC4) のマニュアルページを参照してください。 次の表にも、その概要を掲載しています。

複素数ライブラリ関数 

デフォルトエラー処理 

exp

オーバーフローが起こった場合は errno ERANGE に設定し、最大複素数を返します。

log、log10

引数がゼロの場合は errno EDOM に設定し、最大複素数を返します。

sinh、cosh

引数の虚部によりオーバーフローが起こる場合は複素数ゼロを返します。引数の実部によりオーバーフローが起こる場合は最大複素数を返します。どちらの場合も errnoERANGE に設定されます。

15.5 入出力

複素数ライブラリでは、次の例に示す複素数のデフォルトの抽出子と挿入子が提供されています。


ostream& operator<<(ostream&, const complex&); // 挿入子
istream& operator>>(istream&, complex&); // 抽出子

抽出子と挿入子の基本的な説明については、「14.2 iostream 操作の基本構造」「14.3.1 iostream を使用した出力」を参照してください。

入力の場合、複素数の抽出子 >> は、(括弧の中にあり、コンマで区切られた) 一組の値を入力ストリームから抽出し、複素数オブジェクトに読み込みます。最初の値が実部の値、 2 番目の値が虚部の値となります。たとえば、次のような宣言と入力文がある場合、


complex x;
cin >> x;

(3.45, 5) と入力すると、複素数 x の値は 3.45 + 5.0i となります。抽出子の場合はこの反対になります。complex x(3.45, 5), cout<<x の場合は、(3.45, 5) と表示されます。

入力データは、通常括弧の中でコンマで区切られた一組の値で、スペースは入れても入れなくてもかまいません。値を 1 つだけ入力したとき (括弧とスペースは入力してもしなくても同じ) は、抽出子は虚部をゼロとします。シンボル i を入力してはいけません。

挿入子は、複素数の実部と虚部をコンマで区切り、全体を括弧で囲んで挿入します。シンボル i は含まれません。2 つの値は double 型として扱われます。

15.6 混合演算

complex 型は、組み込みの算術型と混在した式でも使用できるように定義されています。混合算術演算においては、算術型は自動的に complex 型に変換されます。 算術演算子のすべてと数学関数のほとんどに対して、complex 型を使用できるバージョンが提供されています。次に例を示します。


int i, j;
double x, y;
complex a, b;
a = sin((b+i)/y) + x/j;

b+i という式は混合算術演算です。整数 i は、コンストラクタ complex::complex(double,double=0) によって、complex 型に変換されます。このとき、まず整数から double 型に変換されます。b+i の計算結果を double 型の y で割っているので、y もまた complex 型に変換され、複素数除算演算が使用されます。商もまた complex 型ですので、複素数の正弦関数が呼び出され、その結果も complex 型になります。 次も同様です。

ただし、すべての算術演算と型変換が暗黙に行われるわけではありませんし、定義されていないものもあります。たとえば、複素数は数学的な意味での大小関係が決められないので、比較は等しいか否かの判定しかできません。


complex a, b;
a == b; // OK
a != b; // OK
a <  b; // エラー: 演算子 < は complex 型に使用できない
a >= b; // エラー: 演算子 >= は complex 型に使用できない

同様に、complex 型からそれ以外の型への変換もはっきりした定義ができないので、そのような自動変換は行われません。変換するときは、実部または虚部を取り出すのか、または絶対値を取り出すのかを指定する必要があります。


complex a;
double f(double);
f(abs(a)); // OK
f(a);      // エラー: f(complex) は、引数の型が一致していない

15.7 効率

クラス complex は効率も考慮して設計されています。

非常に簡単な関数が inline で宣言されており、関数呼び出しのオーバーヘッドをなくしています。

効率に差があるものは、関数が多重定義されています。たとえば、pow 関数には引数が complex 型のもののほかに、引数が double 型と int 型のものがあります。その方が double 型と int 型の計算がはるかに簡単になるからです。

complex.h をインクルードすると、C の標準数学ライブラリヘッダー math.h も自動的にインクルードされます。C++ の多重定義の規則により、次のようにもっとも効率の良い式の評価が行われます。


double x;
complex x = sqrt(x);

この例では、標準数学関数 sqrt(double) が呼び出され、その計算結果が complex 型に変換されます。 最初に complex 型に変換され、sqrt(complex) が呼び出されるのではありません。これは、多重定義の解決規則から決まる方法で、もっとも効率の良い方法です。

15.8 複素数のマニュアルページ

複素数演算ライブラリの情報は、次のマニュアルページに記載されています。

表 15–3 complex 型のマニュアルページ

マニュアルページ 

概要 

cplx.intro(3CC4)

複素数ライブラリ全体の紹介 

cartpol(3CC4)

直角座標と極座標の関数 

cplxerr(3CC4)

エラー処理関数 

cplxexp(3CC4)

指数、対数、平方根の関数 

cplxops(3CC4)

算術演算子関数 

cplxtrig(3CC4)

三角関数 

第 16 章 ライブラリの構築

この章では、ライブラリの構築方法を説明します。

16.1 ライブラリとは

ライブラリには 2 つの利点があります。まず、ライブラリを使えば、コードをいくつかのアプリケーションで共有できます。共有するコードがある場合は、そのコードを含むライブラリを作成し、コードを必要とするアプリケーションとリンクできます。次に、ライブラリを使えば、非常に大きなアプリケーションの複雑さを軽減できます。アプリケーションの中の、比較的独立した部分をライブラリとして構築および保守することで、プログラマはほかの部分の作業により専念できるようになるためです。

ライブラリの構築とは、.o ファイルを作成し (コードを -c オプションでコンパイルし)、これらの .o ファイルを CC コマンドでライブラリに結合することです。ライブラリには、静的 (アーカイブ) ライブラリと動的 (共有) ライブラリがあります。

静的 (アーカイブ) ライブラリの場合は、ライブラリのオブジェクトがリンク時にプログラムの実行可能ファイルにリンクされます。アプリケーションにとって必要な .o ファイルだけがライブラリから実行可能ファイルにリンクされます。静的 (アーカイブ) ライブラリの名前には、通常、接尾辞 .a が付きます

動的 (共有) ライブラリの場合は、 ライブラリのオブジェクトはプログラムの実行可能ファイルにリンクされません。 その代わりに、プログラムがこのライブラリに依存することをリンカーが実行可能ファイルに記録します。プログラムが実行されるとき、システムは、プログラムに必要な動的ライブラリを読み込みます。同じ動的ライブラリを使用する 2 つのプログラムが同時に実行されると、ライブラリはこれらのプログラムによって共有されます。動的 (共有) ライブラリの名前には、接尾辞として .so が付きます

共有ライブラリを動的にリンクすることは、アーカイブライブラリを静的にリンクすることに比べていくつかの利点があります。

ただし、動的ライブラリには短所もあります。

16.2 静的 (アーカイブ) ライブラリの構築

静的 (アーカイブ) ライブラリを構築する仕組みは、実行可能ファイルを構築することに似ています。一連のオブジェクト (.o) ファイルは、CC-xar オプションを使うことで 1 つのライブラリに結合できます。

静的 (アーカイブ) ライブラリを構築する場合は、ar コマンドを直接使用せずに CC -xar を使用してください。C++ 言語では一般に、従来の .o ファイルに収容できる情報より多くの情報 (特に、テンプレートインスタンス) をコンパイラが持たなければなりません。-xar オプションを使用すると、テンプレートインスタンスを含め、すべての必要な情報がライブラリに組み込まれます。make ではどのテンプレートファイルが実際に作成され、参照されているのかがわからないため、通常のプログラミング環境でこのようにすることは困難です。CC -xar を指定しないと、参照に必要なテンプレートインスタンスがライブラリに組み込まれないことがあります。次に例を示します。


% CC -c foo.cc # main を含むファイルをコンパイルし、テンプレートオブジェクトを作成する
% CC -xar -o foo.a foo.o # すべてのオブジェクトを 1 つのライブラリに集める

-xar フラグによって、CC が静的 (アーカイブ) ライブラリを作成します。-o 命令は、新しく作成するライブラリの名前を指定するために必要です。コンパイラは、コマンド行のオブジェクトファイルを調べ、これらのオブジェクトファイルと、テンプレートリポジトリで認識されているオブジェクトファイルとを相互参照します。 そして、ユーザーのオブジェクトファイルに必要なテンプレートを (本体のオブジェクトファイルとともに) アーカイブに追加します。


注 –

既存のアーカイブのみを作成または更新するには、-xar フラグを使用します。このフラグをアーカイブの保守に使用しないでください。-xar オプションは ar -cr を実行するのと同じことです。


1 つの .o ファイルには 1 つの関数を入れることをお勧めします。アーカイブとリンクする場合、特定の .o ファイルのシンボルが必要になると、.o ファイル全体がアーカイブからアプリケーションにリンクされます。.o ファイルに 1 つの関数を入れておけば、アプリケーションにとって必要なシンボルだけがアーカイブからリンクされます。

16.3 動的 (共有) ライブラリの構築

動的 (共有) ライブラリの構築方法は、コマンド行に -xar の代わりに -G を指定することを除けば、 静的 (アーカイブ) ライブラリの場合と同じです。

ld は直接使用しないでください。静的ライブラリの場合と同じように、CC コマンドを使用すると、必要なすべてのテンプレートインスタンスがテンプレートリポジトリからライブラリに組み込まれます (テンプレートを使用している場合)。アプリケーションにリンクされている動的ライブラリでは、すべての静的コンストラクタは main() が実行される前に呼び出され、すべての静的デストラクタは main() が終了したあとに呼び出されます。dlopen() で共有ライブラリを開いた場合、すべての静的コンストラクタは dlopen() で実行され、すべての静的デストラクタは dlclose() で実行されます。

動的ライブラリを構築するには、必ず CC に -G を使用します。ld (リンクエディタ) または cc (C コンパイラ) を使用して動的ライブラリを構築すると、例外が機能しない場合があり、ライブラリに定義されている大域変数が初期化されません。

動的 (共有) ライブラリを構築するには、 CC-Kpic-KPIC オプションで各オブジェクトをコンパイルして、再配置可能なオブジェクトファイルを作成する必要があります。次に、これらの再配置可能オブジェクトファイルから動的ライブラリを構築します。原因不明のリンクエラーがいくつも出る場合は、-Kpic-KPIC でコンパイルしていないオブジェクトがある可能性があります。

ソースファイル lsrc1.cclsrc2.cc から作成するオブジェクトファイルから C++ 動的ライブラリ libfoo.so を構築するには、次のようにします。


% CC -G -o libfoo.so -h libfoo.so -Kpic lsrc1.cc lsrc2.cc

-G オプションは、動的ライブラリの構築を指定しています。-o オプションは、ライブラリのファイル名を指定しています。-h オプションは、共有ライブラリの名前を指定しています。-Kpic オプションは、オブジェクトファイルが位置に依存しないことを指定しています。


注 –

CC -G コマンドは -l オプションを ld に渡しません。共有ライブラリにほかの共有ライブラリとの依存関係を持たせる場合、 必要な -l オプションをコマンド行に指定する必要があります。たとえば、共有ライブラリに libCrun.so との依存関係を持たせる場合、-lCrunをコマンド行に指定する必要があります。


16.4 例外を含む共有ライブラリの構築

C++ コードが含まれているプログラムでは、-Bsymbolic を使用せずに、リンカーのマップファイルを使用してください。-Bsymbolic を使用すると、異なるモジュール内の参照が、本来 1 つの大域オブジェクトの複数の異なる複製に結合されてしまう可能性があります。

例外メカニズムは、アドレスの比較によって機能します。オブジェクトの複製が 2 つある場合は、アドレスが同一であると評価されず、本来一意のアドレスを比較することで機能する例外メカニズムで問題が発生することがあります。

dlopen() を使用して共有ライブラリを開いている場合は、 例外メカニズムが機能するには RTLD_GLOBAL を使用する必要があります。

16.5 非公開ライブラリの構築

ある組織の内部でしか使用しないライブラリを構築する場合には、一般的な使用には適さないオプションを使ってライブラリを構築することもできます。具体的には、ライブラリはシステムのアプリケーションバイナリインタフェース (ABI) に準拠していなくてもかまいません。たとえば、ライブラリを -fast オプションでコンパイルして、特定のアーキテクチャー上でのパフォーマンスを向上させることができます。同じように、-xregs=float オプションでコンパイルして、パフォーマンスを向上させることもできます。

16.6 公開ライブラリの構築

ほかの組織からも使用できるライブラリを構築する場合は、ライブラリの管理やプラットフォームの汎用性などの問題が重要になります。ライブラリを公開にするかどうかを決める簡単な基準は、アプリケーションのプログラマがライブラリを簡単に再コンパイルできるかどうかということです。公開ライブラリは、システムの ABI に準拠して構築しなければなりません。一般に、これはプロセッサ固有のオプションを使用しないということを意味します。たとえば、-fast-xtarget は使用しないようにします。

SPARC ABI では、いくつかのレジスタがアプリケーション専用で使用されます。V7 と V8 では、これらのレジスタは %g2%g3%g4 です。V9 では、これらのレジスタは %g2%g3 です。ほとんどのコンパイルはアプリケーション用に行われるので、C++ コンパイラは、デフォルトでこれらのレジスタを一時レジスタに使用して、プログラムのパフォーマンスを向上しようとします。しかし、公開ライブラリでこれらのレジスタを使用することは、SPARC ABI に適合しないことになります。公開ライブラリを構築するときには、アプリケーションレジスタを使用しないようにするために、すべてのオブジェクトを -xregs=no%appl オプションで コンパイルしてください。

16.7 C API を持つライブラリの構築

C++ で作成されたライブラリを C プログラムから使用できるようにするには、C API を作成する必要があります 。そのためには、エクスポートされるすべての関数を extern "C" にします。ただし、これができるのは大域関数だけで、メンバー関数にはできません。

C インタフェースライブラリで C++ の実行時サポートを必要とし、しかも cc とリンクしている場合は、C インタフェースライブラリを使用するときにアプリケーションも libC (互換モード) または libCrun (標準モード) にリンクする必要があります。C インタフェースライブラリで C++ 実行時サポートが不要の場合は、libClibCrun とリンクする必要はありません。リンク手順は、アーカイブされたライブラリと共有ライブラリでは異なります。

アーカイブされた C インタフェースライブラリを提供するときは、ライブラリの使用方法を説明する必要があります。

共有 C インタフェースライブラリを提供するときは、ライブラリの構築時に libC または libCrun と依存関係をつくる必要があります。共有ライブラリの依存関係が正しければ、ライブラリを使用するときに -lC または -lCrun をコマンド行に追加する必要はありません。

さらに、C++ 実行時ライブラリにもまったく依存しないようにするには、 ライブラリソースに対して次のコーディング規則を適用する必要があります。

16.8 dlopen を使って C プログラムから C++ ライブラリにアクセスする

C プログラムから dlopen で C++ 共有ライブラリを開く場合は、共有ライブラリが適切な C++ 実行時ライブラリ (-compat=4 の場合は libC.so.5-compat=5 の場合は libCrun.so.1) に依存していることを確認してください。

そのためには、共有ライブラリを構築するときに、-compat=4 の場合は -lC-compat=5 の場合は -lCrun を次のようにコマンド行に追加します。次に例を示します。


example% CC -G -compat=4... -lC
example% CC -G -compat=5... -lCrun

共有ライブラリが例外を使用している場合には、ライブラリが C++ 共有ライブラリに依存していないと、C プログラムが正しく動作しないことがあります。


注 –

共有ライブラリを dlopen() で開く場合は、RTLD_GLOBAL を使用しないと、例外は機能しません。