使用するライブラリを作成したいのですが、ヘッダーファイルを1つだけ含める必要があります。ただし、複数のソースファイルがあり、両方にヘッダーが含まれている場合、ライブラリがヘッダーで宣言および定義されているため、複数の定義エラーが発生します。Boostでは、ヘッダーのみのライブラリを見たことがあります。彼らはどうやってそれをしましたか?
4 に答える
functions を宣言inline
し、それらを名前空間に配置して、衝突しないようにします。
namespace fancy_schmancy
{
inline void my_fn()
{
// magic happens
}
};
Boost が主にヘッダーのみである主な理由は、テンプレート指向が強いためです。テンプレートは通常、1 つの定義ルールからパスを取得します。実際、テンプレートを効果的に使用するには、テンプレートを使用するすべての翻訳単位で定義を表示する必要があります。
1 つの定義規則 (ODR) を回避する別の方法は、inline
関数を使用することです。実際には、ODR からフリーパスを取得するinline
ことが実際に行われることです。関数をインライン化する可能性があるという事実は、実際にはオプションの副作用です。
最後のオプション (ただし、おそらくそれほど良くはありません) は、関数を静的にすることです。これらすべての関数インスタンスが実際には同じであることをリンカーが判断できない場合、これはコードの肥大化につながる可能性があります。しかし、完全を期すために言及します。static
としてマークされていなくても、コンパイラは関数をインライン化することが多いことに注意してくださいinline
。
Boost はヘッダーのみのライブラリを多く使用します。これは、STL と同様に、クラスと関数のテンプレートを使用して構築されているためです。ほとんどの場合、ヘッダーのみです。
テンプレートを作成していない場合は、ヘッダー ファイルにコードを含めることは避けたいと思います。これを単純な古い静的ライブラリにします。
多くの本当にヘッダーのみの Boost ライブラリがありますが、それらは非常に単純 (および/またはテンプレートのみ) である傾向があります。より大きなライブラリは、いくつかの策略によって同じ効果を達成します。それらには「自動リンク」があります (この用語がここで使用されていることがわかります)。基本的に、ヘッダーには、プラットフォームに適した lib ファイルを見つけ出し、a を使用し#pragma
てリンカにリンクするように指示する一連のプリプロセッサ ディレクティブがあります。したがって、明示的にリンクする必要はありませんが、リンクされています。 .