まず、inline
クラス内で定義された関数にキーワードを使用することは完全に合法です。
struct MyClass
{
inline int someFunctions() { return 42; }
};
ここでのキーワードは冗長ですが、違法ではありません。
次に、inline
キーワードはコンパイラへのヒントとなることを目的としていますが、1つの定義規則に違反することで未定義の動作を引き起こすことなく、関数の複数の定義を許可することが唯一の正式な必須の意味です。また、コンパイラは場合によってはそれを無視します。
ほとんどのコンパイラは、デバッグ用に設計されたオプションが指定されている場合(または最適化がオフになっている場合)にそれを無視し、実際には何もインライン化しません。
最大最適化がオンになっている場合、最高のコンパイラはそれを完全に無視します。関数がインライン化されるかどうかは、コードとプロファイリングデータのコンパイラーの分析に一意に依存し、特定の関数は、別の場所ではなく、ある場所(タイトループの真ん中にある場所)にインライン化されます。(そして、他のポスターが言っていることとは異なり、これは、呼び出しサイトと関数定義が2つの異なる変換単位にある場合でも発生します。)
これら2つの極端な状況の間では、多くのコンパイラーはモジュール間分析を行わず、少なくともある程度の最適化がオンになっている場合、少なくともほとんどの場合、「ヒントを得る」でしょう。
たとえば、コンパイラがコンパイル時に再帰の深さを判別できない場合、再帰インライン関数はほぼ確実にインラインで生成されません。また、ほとんどのコンパイラは、ローカライズされた静的分析でオブジェクトの実際のタイプを判別できない場合、仮想関数をインラインで生成できませんが、特定のオーバーロードが99%の確率で呼び出されることを示す、特定のプロファイラー出力の一部が最適です。 、を生成しif
、その1つのケースをインライン化する場合があります。
一般に、ヘッダーファイルでの定義はできるだけ少なくする必要があるため、「エクスポートされた」クラスのinline
場合、プロファイラーが絶対に必要であると言わない限り、(明示的または暗黙的に)使用しません。ソースファイルで定義されているローカルクラスの場合、クラス定義で関数を定義するかどうかはスタイルの問題です(そして、コンパイラがそれらをインライン化するかどうかについては、違いが生じる場合とそうでない場合があります。通常のデバッグオプションでは、ほとんどのコンパイラは何もインライン化しません)。