私はC++の良い習慣を使って、以前に書いたコードを書き直そうとしています。このような目標を達成するために、参考として使用しています Effective C++ (1)と googleコーディング規約 (2)。 (2)によると、関数が10行以下の場合はインラインで宣言する必要があります。(1)によれば、コンパイラはインラインディレクティブを無視できます。たとえば、ループや再帰がある場合(いくつかの例が提供されるだけなので、コンパイラによって無視されるすべてのケースを知っているわけではありません)。
次に、2つの関数があるとします。最初の関数は10行です。他の関数への呼び出しはなく、一般に外部参照はありません。 2番目はまだ10行であると想定していますが、ある時点で最初の1行が呼び出されます
何かのようなもの
Type1 f(Type2 arg) {
//10 lines of self contained code
}
Type3 g(Type4 arg) {
//0 <= n <= 8 lines of code
//g(x);
//9 - n lines of code
}
Googleからの提案により、f
をインラインで宣言します(完全に正当化されます)が、g
について戸惑うことになるでしょう。 g
をインラインとして宣言するとコンパイラは無視しますか?できない場合でも、インラインディレクティブの利点を利用できますか?
C++では、inline
指定子は、コンパイラーが関数呼び出しをインライン化するかどうかには影響しません。インライン化を可能にする効果がありますが、それが主な目的ではありません。インライン化したいプライベートヘルパー関数がある場合は、代わりに、その関数に内部リンケージがあることを確認してください。匿名の名前空間に配置する(C++ 11)。内部リンケージのある宣言には、現在のコンパイル単位内からのみアクセスできます。
inline
関数は複数の定義を持つことができます。これは、ヘッダーファイル内で関数を定義するときに重要です。通常、関数はヘッダーで宣言し、それを.cppファイルに実装します。他のコンパイル単位はヘッダーに宣言を含み、後で定義にリンクされます。ただし、関数がヘッダーで定義されている場合、同じ関数が複数のコンパイル単位に存在します。それらがリンクされると、リンカーは関数のこれらの複数の定義を参照します。正しい定義はどれですか?リンカはエラーを発生させます。
inline
指定子を使用して、これらの複数の定義に問題がなく、すべて同じ関数を参照していることをリンカーに通知します。さらに、inline
関数の定義は同じコンパイル単位に存在する必要があります。
一部の関数は暗黙的にインライン化されています。特に、クラス宣言内のメソッドと関数は次のとおりです。
class Foo {
public:
void method() { /* implicitly inline */ }
static void static_method() { /* implicitly inline */ }
friend void friend_function() { /* implicitly inline */ }
};
void free_function() { /* not implicitly inline */ }
関数は短いので、インラインとして宣言しないでください。ヘッダーで定義したため、インラインとして宣言します。
さらに読む: inline
cppreference.comの指定子
引用するGoogleスタイルガイドでは、inline
キーワードを使用するタイミングについては説明していませんが、関数をインラインで(つまり、ヘッダーファイルに)実装する必要があるかどうかを説明しています。クラスのゲッターのような単純な関数の場合、これは通常完全に問題ありません。大規模で複雑な関数の場合、通常は個別に実装することをお勧めします(これはテンプレートでは不可能です)。