このプロジェクト (http://www.savarese.com/software/libssrccdtree/) を見ると、「C++ ヘッダーのみのテンプレート ライブラリ」という定義が見つかりました。現時点では、基本的な C++ の知識はありますが、これが正確に何を意味するのか、なぜこのプロジェクトでこの人々がそれを使用するのかを知りたいと思っています。
9 に答える
これは、テンプレート(関数テンプレートまたはクラステンプレート)のすべての定義がヘッダーのみにあることを意味します。ファイルはありません.cpp
。ファイルのみがあり.h
ます(または、などの拡張子がまったくない、またはまったくないなどのその他の.hpp
拡張子)<vector>
string>
C ++コンパイラでは、テンプレートの定義が、それらが宣言されているのと同じファイルに存在する必要があります。そのため、ヘッダーのみのライブラリは静的ライブラリでも動的ライブラリでもありません。そのソースコードライブラリは、ヘッダーで実装を確認できることを意味します。コードにヘッダーファイルをインクルードしました。これは、ライブラリのヘッダーと一緒にコンパイルされます。
<vector>
、、などstring>
のテンプレートを使用するC ++標準ライブラリの一部は、<map>
ヘッダーのみのライブラリであることに注意してください。
実際には、テンプレート(クラステンプレートと関数テンプレート)を静的または動的ライブラリにコンパイルしてプログラムにリンクすることはできません。テンプレートは、用語自体が言うように、テンプレートです。これは通常のコードではありません。テンプレート引数(またはのいずれtype
かvalue
)を渡すコードで使用する場合にのみ、コンパイラは関数/クラステンプレートからコンパイル可能な関数/クラスを生成します。
template<typename T>
struct A
{
T data;
};
struct B
{
int data;
};
ここでA
は、コンパイラが何であるかを知らないため、バイナリ(静的ライブラリまたは動的ライブラリ)にコンパイルすることはできませんT
。ただしB
、コンパイラには完全な情報があるため、バイナリにコンパイルできます。
したがって、 「クラステンプレートA」というフレーズは、 :がクラスのテンプレートであると読むことができますA
。A
それ自体はクラスではありません。しかしB
、これはクラスであり、テンプレートではありません。
クラステンプレートA
を静的または動的ライブラリにコンパイルしてプログラムにリンクすることはできないため、完全なソースコードを含むライブラリA
としてのみ出荷できます。header-only
同じく
一部のライブラリは、使用可能なクラスまたは関数を定義するヘッダー ファイルと共に、プロジェクトにリンクする必要があるバイナリ ファイルの形式をとります。「ヘッダーのみのライブラリ」とは、バイナリ ファイルを含まず、ソースに含めるヘッダーのみを含むライブラリです。
テンプレートは、特定の用途に合わせてカスタマイズされたクラスまたは関数です。コンパイラはソースを読み取ってカスタマイズする必要があるため、通常はヘッダー ファイルで定義されます。テンプレートがどのように使用されるかを正確に把握するまで、テンプレートをバイナリ ファイルにコンパイルすることはできません。そのため、独自のコードと共にソースを含めると、コンパイラはそれらを一緒に処理できます。
これは、ライブラリがヘッダーとしてのみ再配布されることを正確に意味します。これを使用するには、ソースファイルに#includeするだけで済みます。
簡単に言うと、テンプレートはコンパイラがコードを生成するためのマクロによく似ているということです。インスタンス化するたびに(esampleの場合、のような型を使用して)、コンパイラは、テンプレートクラスのコードにstd::list<int>
正しい型(この場合)を挿入するための元のコードを持っている必要があります。int
これが、テンプレートクラスを.h
ファイルで使用するたびにファイルに含まれる理由.cpp
です。
これは、すべてのコードがヘッダー ファイルにあることを意味します。ライブラリに関連付けられているライブラリはありません。それが実際に何を意味するかは、状況によって異なります — 最悪の場合、作成者がコードをコンパイルさえしていないことを意味します:-)。ほとんどの場合、使用するコンパイラ、バージョン、およびオプションの正確な組み合わせでコードがテストされたことがないため、コンパイル時間が大幅に増加します。一方、作成者があなたと同じコンパイラにアクセスできなくてもライブラリを使用でき、ライブラリをコンパイルしたときに彼が使用したオプションを使用することを強制されないことを意味します。または、オープン ソースの場合は、ライブラリを自分で構築する必要はありません。
これは、ライブラリにモジュールがなく、ヘッダーのみがあることを意味します。つまり、ライブラリを最初にコンパイルして後でリンクする必要なしに使用できます。独自のソースモジュールにヘッダーを含めるだけです。
このアプローチの利点は次のとおりです。
- ビルドシステムでリンカーオプションを指定する必要がないため、含める方が簡単です。
- ライブラリの関数はコードにインライン化されるため、常にすべてのライブラリコードを残りのコードと同じコンパイラ(オプション)でコンパイルします。
- それははるかに速いかもしれません。
この場合、コンテナのデータ構造は、含まれるデータのタイプに基づいてテンプレート化されて実装されているため、完全にコンパイルすることはできません。
テンプレートライブラリの場合、従来のコンパイラは特定のタイプをインスタンス化するためにテンプレートクラスの完全な定義を必要としていたため、ヘッダー(.hファイル)だけですべての機能を提供できます。ライブラリが事前にインスタンス化されたバージョンを提供する場合、またはテンプレート化する必要のないテンプレートライブラリの一部がある場合を除いて、ライブラリに入れるものは何もありません。
個別の.cppファイルが含まれておらず、.hファイルのみが含まれているため、「ヘッダーのみ」であり、#include
すべてのライブラリコードをコードに含めることができます。
これは、非常に苦痛になる可能性のある静的ライブラリに対してリンクする必要がないため、有利な場合があります。
これは、開発のリンク段階で外部ライブラリをリンクする必要がないことを意味します。ライブラリをダウンロードし、#includeマクロを使用するだけでライブラリを使用できます。これにより、将来のアプリケーションのデプロイが簡素化されますが、コンパイラ時間が長くなる場合があります。