プログラミング原人の進化ログ

プログラミング原人の進化論

オレ プログラミング ベンキョウ スル。マナンダ コト カク。

【C++】インライン関数

C++にはインライン関数を使う機能があります。その使い方のまとめです。

目標

  • インライン関数が何者か理解する
  • C++でインライン関数を使えるようになる

インライン関数とは?

通常の関数は、呼び出すたびにメモリのどこかに存在するその関数を(関数へのポインタによって)探し出し、そこへ移動して処理を行い、必要であれば返り値を返します。

それに対して、インライン関数は呼び出し場所にインライン展開されます。インライン展開というのは、ソースコードコンパイルしたときに、インライン関数の呼び出しが関数の処理内容に置き換えられることです。つまり、インライン関数を呼び出すことは(便宜上「呼び出す」と言いますが、実際に呼び出しが行われる訳ではありません)、そこに処理を直接書いてしまうことと同じことであると言えます。

なぜインライン関数を使うのか

呼び出しが行われないことによって、プログラムの実行速度の高速化につながります。これがインライン関数を使う上での利点です。実行速度が改善されるのは、通常の関数を呼び出すときに必要な、呼び出しの準備、引数をスタックに積む、値を返すなどの動作が必要なくなるためです。

ただし、インライン関数がいくつもの処理を行う大きな関数である場合、インライン展開によってソースファイルのサイズが大きくなってしまいます。したがって、インライン関数にするのに適しているのは処理の少ない小さな関数です。

インライン関数を作るには、inline修飾子を使う方法と、クラス内で関数を定義するという2つの方法があります。

作り方1:inline修飾子を使う

関数を定義するとき、最初にinline修飾子をつけます。

例:

#include<iostream>
using namespace std;

inline int add2(int x) {
  return x + 2;
}

int main() {  
  cout << add2(1) << " " << add2(3) << endl;  // 3 5
  
  return 0;
}

実行結果:

3 5

ちなみに、あるクラスのメンバ関数をクラス外で定義するときには、クラス内での宣言時にinlineはつけません。具体的に処理を定義するときだけinlineをつけます。

なお、inlineキーワードを用いても、パフォーマンスを鑑みた結果、コンパイラがインライン関数にしないと判断してインライン展開がなされない場合もあります。これはコンパイラによります。

作り方2:クラス内で関数を定義する

クラス内で定義された関数は、自動的にインライン関数となります。一般的に、小さな関数はクラス内で定義します。

例:

#include<iostream>
using namespace std;

class myClass {
  int m_i;

public:
  int get() {
    return m_i;
  }

  void set(int i) {
    m_i = i;
  }
};

int main() {
  myClass a;

  a.set(1);
  cout << a.get() << endl;  // 1
  a.set(3);
  cout << a.get() << endl;  // 3
  
  return 0;
}

実行結果

1
3

まとめ

インライン関数について勉強しました。名前はいかついですが(そうでもない?)、使い方は簡単ですね。

参考

ハーバート・シルト(2009)「標準講座C++」柏原正三訳・監修 株式会社トップスタジオ