1. ホーム
  2. c++

[解決済み] インライン変数の仕組みは?

2022-04-26 16:15:48

質問

2016年のオウルISO C++標準化会議では、以下のような提案がなされました。 インライン変数 は、標準化委員会によってC++17に投票されました。

平たく言えば、インライン変数とは何か、どのように機能し、何に役立つのか。インライン変数はどのように宣言し、定義し、使用すべきなのでしょうか?

どのように解決するのですか?

提案の最初の文章です。

<ブロッククオート

" inline は、関数だけでなく、変数にも適用することができます。

の¹保証された効果 inline 関数に適用すると、その関数を複数の翻訳ユニットで外部リンク付きで同一に定義できるようになります。実際には、ヘッダーで関数を定義することで、複数の翻訳ユニットに含めることができます。本提案では、この可能性を変数に拡張する。

つまり、実用面では、(現在受け入れられている)提案では inline キーワードを使用して、外部リンクを定義します。 const 名前空間スコープ変数、または任意の static そのため、そのヘッダが複数の翻訳ユニットに含まれる場合、複数の定義があってもリンカは問題ありません。 一つ そのうちの

C++14までは、このための内部機構がありました。 static という変数がクラステンプレートに含まれていますが、そのメカニズムを使用する便利な方法はありませんでした。そのため、次のようなトリックに頼らざるを得ませんでした。

template< class Dummy >
struct Kath_
{
    static std::string const hi;
};

template< class Dummy >
std::string const Kath_<Dummy>::hi = "Zzzzz...";

using Kath = Kath_<void>;    // Allows you to write `Kath::hi`.

C++17以降では、以下のように書くことができると思います。

struct Kath
{
    static std::string const hi;
};

inline std::string const Kath::hi = "Zzzzz...";    // Simpler!

... ヘッダーファイルの中で

この提案には、以下の文言が含まれています。

" インライン静的データメンバは、クラス定義で定義し、brace-or-equal-initializer を指定することができる。もし、そのメンバが constexpr 指定子により、初期化子なしで名前空間スコープで再宣言することができる(この使用法は非推奨。) 他の静的データメンバの宣言は,brace-or-equal-initializerを指定してはならない。

...これにより、上記はさらに単純化され、以下のようになります。

struct Kath
{
    static inline std::string const hi = "Zzzzz...";    // Simplest!
};

... T.C.が指摘したように コメント をこの回答に追加しました。

また  ​constexpr 指定子は  inline  は、関数と同様に静的データメンバにも適用されます。


注意事項

¹ 関数の場合 inline には、この関数の呼び出しを機械語に直接置き換えることを勧めるという、 最適化に関するヒンティング効果があります。このヒンティングは無視することができる。