web-dev-qa-db-ja.com

クラス定義で定義されたC ++メンバー関数で「インライン」暗黙的ですか

C++仕様によると、次の2つのクラスは同等に定義されていますか?

class A
{
   void f()
   {
   }
};

class B
{
   inline void f()
   {
   }
};

つまり、クラス定義で定義されたそのようなメンバー関数に「インライン」修飾子を配置することは完全に冗長ですか?

次の質問:コードスタイルの場合、冗長であると仮定すると、「インライン」タグを保持するのが賢明であるため、将来の開発者は、関数をインライン化する必要があることを認識し、どこか別の場所で定義を削除してインライン化を削除しませんか?

ありがとう:)

36
Sam

これらは、単一定義規則の目的を除いて、同等のクラス定義です。したがって、この標準では、1つのTU(変換単位)を1つのクラス定義でコンパイルし、別のTUを他のクラス定義でコンパイルして、それらをリンクできることを保証していません。一緒に。これが実際の実装で実際に失敗することはないと思いますが、それは標準が言っていることです。

inlineキーワードは、インライン化とはほとんど関係ありません。関数の複数の同一の定義が異なるTUで許可されるかどうかについてです。誰かが関数定義を別の場所に移動した場合、次の基準でそれをinlineとマークするかどうかを決定する必要があります。

  • そのクラスの.cppファイルにある場合、そのTUからのみ呼び出される場合は、inlineとマークするのが有効です。その場合、inlineとマークされているかどうかはおそらく違いはありませんが、コンパイラが必要なことに注意を払うと思われる場合は、コンパイラのヒントとしてinlineとマークすることができます。

  • まだヘッダーファイルにある場合は、inlineとマークする必要があります。そうしないと、ヘッダーを使用するさまざまなTUをリンクするときに複数の定義エラーが発生します。

関数を動かす人がそれらのことを知っていると仮定すると、クラス定義でリマインダーは必要ないと思います。それらのことを知らない場合は、おそらく関数を移動するビジネスはありませんが、inlineキーワードを使用して移動する方が安全です。

20
Steve Jessop

C++ ISO標準によると:

クラス定義内で定義された関数はインライン関数です。

ただし、これは、関数が必ずしもインライン化されることを意味するわけではありません。一般に、最近では、関数をインライン化することで何らかの利点が得られるかどうかをコンパイラが決定するようです。

92
craigmj

クラス定義で定義されたそのようなメンバー関数に「インライン」修飾子を配置することは完全に冗長ですか?

はい

コードスタイルの場合、「インライン」タグを保持するのが賢明なので、将来の開発者は関数をインライン化する必要があることを認識し、定義を別の場所で削除してインライン化を削除しませんか?

番号。
インラインは「単一定義規則」用です(したがって、拡張によってリンクされます)。 inlineが必要な場所で関数が定義されていて、それが提供されていない場合、コンパイル時エラーになります。それが必要でない場合、それは単に余分な役に立たない綿毛です。

したがって、必要がない場合は削除してください。必要な場合はそこに置いてください(忘れた場合はコンパイラが通知します)。

9
Martin York

その場合、インラインはオプションです。コンパイラーはそれがインラインであることを認識し、ヘッダーが含まれている場合は常に関数の複数のインスタンスを生成しません。

そのままにしておくのがいいかどうかについては、あまりそうは思いません。関数をインライン化する必要がある理由を説明する詳細なコメントを提供することをお勧めします(そのうち、2つの理由だけを間引くことができます:「テンプレートです」(裏打ちが不可能な場合)または「パフォーマンス」(この場合)いくつかの場所で見た「インラインであるため、パフォーマンスを向上させる必要がある」というよりも、いくつかの裏付けとなる証拠を見たいと思います。

2
Tom Tanner