ヘッダファイルを考えてみます。
class T
{
private:
int const ID;
public:
explicit T(int const ID_) noexcept : ID(ID_) {}
int GetID() const noexcept { return ID; }
};
または、代わりに:
class T
{
private:
int const ID;
public:
explicit T(int const ID_) noexcept;
int GetID() const noexcept;
};
inline T::T(int const ID_) noexcept : ID(ID_) {}
inline int T::GetID() const noexcept { return ID; }
前のモジュールの世界では、これらのヘッダは、テキストでODR違反することなく、複数のTUに含まれている場合があります。さらに、関与するメンバ関数が比較的小さいため、コンパイラだろう可能性が高い「インライン」(避ける関数呼び出しを使用して)のいくつかの場合、これらの機能、あるいは最適化離れてT
完全に。
最近ではレポート C ++ 20が終了した会議で、私は次の文を読むことができます:
私たちは、の意味を明確に
inline
モジュールのインターフェイスに:意図が明示的に宣言されていない関数の本体は、ということですinline
これらの関数の本体は、モジュールのインターフェイスに表示されていても、モジュールのABIの一部ではありません。モジュールの著者が自分ABIをより詳細に制御を与えるために、モジュールインターフェースのクラス体で定義されたメンバ関数は、暗黙的にもはやありませんinline
。
私は私がいることを間違っていないか分かりません。どういう意味コンパイラは、関数を離れて最適化することができるようにするために、モジュールの世界では、ということは、私たちのように、それらに注釈を付ける必要があり呼び出すことinline
それらがでクラスに定義されている場合でも?
その場合は、以下のモジュールインターフェースは、上記のヘッダに相当するでしょうか?
export module M;
export
class T
{
private:
int const ID;
public:
inline explicit T(int const ID_) noexcept : ID(ID_) {}
inline int GetID() const noexcept { return ID; }
};
私はまだモジュールをサポートしたコンパイラを持っていないにもかかわらず、私が使用を開始したいと思いinline
、将来のリファクタリングを最小限に抑えるために、その適切な場合のように。
どういう意味コンパイラは、関数を離れて最適化することができるようにするために、モジュールの世界では、ということは、私たちのように、それらに注釈を付ける必要があり呼び出すこと
inline
それらがでクラスに定義されている場合でも?
ある程度。
インライン化は、最適化「かのように」であり、コンパイラは賢い十分にある場合でも、翻訳単位の間で発生する可能性がインライン展開します。
ことで、単一の翻訳単位内での作業時にインライン化が最も簡単である、と述べました。このように、簡単にインライン化を促進するために、inline
-declared関数は、その定義は、それが使用されているすべての翻訳単位で提供されている必要があります。これが意味するものではありませんコンパイラは確かにインラインで(あるいは確かにインライン任意の非inline
-qualified機能)が、インライン化はTU内ではなく、それらの間で起きていることから、それは、インライン化プロセスに非常に簡単にメイクのことを行います。
前のモジュールの世界では、クラス内で定義されたクラスメンバーの定義は、宣言されているinline
暗黙のうちに。どうして?定義はクラス内なので。前のモジュールの世界では、TUの間で共有されているクラス定義は、テキストを含めることによって共有されています。クラスで定義されたメンバーは、したがって、それらのTUの間で共有ヘッダに定義されます。複数のTUが同じクラスを使用するのであれば、これらの複数のTUは、クラス定義とそのメンバーの定義に含めることによってそうしているヘッダで宣言されました。
それはあなたが定義を含めている、あるとにかくなぜそれをしませんか、inline
?
もちろん、この手段の関数の定義は今、クラスのテキストの一部であること。あなたがメンバーの定義を変更する場合は、この力を再帰的に、そのヘッダを含むすべてのファイルの再コンパイル、ヘッダで宣言されました。クラスのインターフェイス自体は変更されていない場合でも、再コンパイルを行う必要があります。このような機能を行うよう暗黙的にinline
あなたにもそれを行うことができので、これを変更しません。
前のモジュールの世界でこれを回避するには、単に他のファイルに含まれ得ることはありませんC ++ファイルにメンバーを定義することができます。あなたは簡単にインライン化を失っていますが、コンパイル時間を稼ぎます。
しかし、ここことだ:これは、複数の場所にクラスを提供するための手段として、テキストを含めることを使用しての成果物です。
モジュラー世界では、おそらく我々は、Java、C#、Pythonのような他の言語で見るように、クラス自体内の各メンバ関数を定義したい、などが挙げられるでしょう。これは、合理的なコードの局所性を保持し、それは、このようにDRYのニーズに応える、再入力同じ関数シグネチャを有する防ぎます。
すべてのメンバーは、クラス定義内で定義されている場合しかし、その後、古いルールの下で、それらのすべてのメンバーは次のようになりますinline
。そして、関数があることをできるようにするモジュールのためにinline
、バイナリモジュール成果物は、それらの機能の定義を含める必要があります。これはいつでもあなたは、このような関数定義のコードの一つでも行を変更することを意味し、モジュールは再帰的に、それに応じて、すべてのモジュールと一緒に、構築する必要があります。
implicit-削除するinline
モジュールには、クラスの外に定義を移動することなく、ユーザーに彼らは、テキスト包含日にいたのと同じ権限を与えます。あなたは定義はモジュールの一部である機能とされていないものを選ぶことができます。