未使用の関数は、C ++ 14に従って副作用のある変数テンプレートをインスタンス化できますか?

ジャックホワイト

これが私のコードです:

#include <iostream>

class MyBaseClass
{
public:
    static int StaticInt;
};

int MyBaseClass::StaticInt = 0;

template <int N> class MyClassT : public MyBaseClass
{
public:
    MyClassT()
    {
        StaticInt = N;
    };
};

template <int N> static MyClassT<N> AnchorObjT = {};

class UserClass
{
    friend void fn()
    {
        std::cout << "in fn()" << std::endl; //this never runs
        (void)AnchorObjT<123>;
    };  
};

int main()
{
    std::cout << MyBaseClass::StaticInt << std::endl;
    return 0;
}

出力は次のとおりです。

123

...MyClassT()コンストラクターが呼び出されたことfn()がないにもかかわらず、コンストラクターが呼び出されたことを示します。

上でテストgccclang-O0-O3-Osとさえ-Ofast


質問

このプログラムは、C ++標準に従って未定義の動作をしますか?

言い換えると、後のバージョンのコンパイラーfn()がそれが呼び出されないことを検出できた場合、コンストラクターを実行すると同時にテンプレートのインスタンス化を最適化できますか?

このコードをどういうわけか決定論的にすることはできますか?つまり、コンストラクターを強制的に実行することがfnできますか?関数名またはテンプレートパラメーター値を123外部で参照することはありUserClassませんか?


更新:モデレーターが私の質問を切り捨て、さらに切り捨てることを提案しました。元の詳細バージョンはここで表示できます

バリー

テンプレートのインスタンス化はコードの関数であり、動的な実行時条件の関数ではありません。単純な例として:

template <typename T> void bar();

void foo(bool b) {
  if (b) {
    bar<int>();
  } else {
    bar<double>();
  }
}

bar<int>bar<double>両方ともここでインスタンス化されます。呼び出されたことがないfoo場合や、fooでのみ呼び出された場合でも同様ですtrue

変数テンプレートの場合、具体的には、ルールは[temp.inst] / 6です。

変数テンプレートの特殊化が明示的にインスタンス化または明示的に特殊化されていない限り、変数テンプレートの特殊化は、変数定義の存在を必要とするコンテキストで参照される場合、または定義の存在がプログラムのセマンティクスに影響を与える場合に暗黙的にインスタンス化されます。

あなたの機能では:

friend void fn() 
{ 
    (void)AnchorObjT<123>;
};  

AnchorObjT<123>定義を必要とするコンテキストで参照されているため(fn()呼び出されたかどうかに関係なく、この場合は呼び出すことも可能です)、インスタンス化されます。

ただし、AnchorObjT<123>はグローバル変数であるため、そのインスタンス化は、以前に構築されたオブジェクトがあることを意味します。main()入力するまでにmain()AnchorObjT<123>のコンストラクターが実行され、に設定さStaticInt123ます。fn()このコンストラクターを呼び出すために実際に実行する必要はないことに注意してください-fn()ここでの役割は、変数テンプレートをインスタンス化することだけであり、そのコンストラクターは他の場所で呼び出されます。

123の印刷は、予想される正しい動作です。


言語ではグローバルオブジェクトAnchorObjT<123>が存在する必要がありますが、リンカはオブジェクトへの参照がないため、オブジェクトが存在する可能性があることに注意してください実際のプログラムがこのオブジェクトでより多くのことを行うと仮定すると、それが存在する必要がある場合は、リンカーがそれを削除しないようにするために、より多くのことを行う必要があります(たとえば、gccにはused属性があります)。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

テンプレートのインスタンス化の副作用はありますか?

テンプレート引数の一部またはすべてを強制せずに、エンティティがテンプレートクラスのインスタンス化であると静的にアサートできますか?

void swap()を使用して、C ++でこの関数をテンプレート化するときに行った偶然はありますか?

ステートメントまたは関数の副作用を無視するようにコンパイラーに指示できますか?

c ++クラステンプレートはインスタンス化できますが、同じテンプレートパラメータを使用した関数テンプレートのインスタンス化は失敗します

ペアのタプルを可変個引数テンプレートタイプにストリップしたり、可変個引数タイプで何かをインスタンス化する方法はありますか?

テンプレート関数の特定の可変個引数テンプレートクラスから型がインスタンス化されているかどうかを確認するにはどうすればよいですか?

C ++が派生構造体を使用して親テンプレート構造体をインスタンス化し、親テンプレートが子構造体の関数を呼び出すことができるのはなぜですか?

メンバー変数を使用してメンバークラステンプレートをインスタンス化できますか?

C ++が完全な特殊化によってマスクされている基本テンプレート関数をインスタンス化するのはなぜですか?

折り返し式を使用して可変個引数テンプレート関数の各タイプをインスタンス化するにはどうすればよいですか?

テンプレート関数の各インスタンスを作成するときに、テンプレート関数のtypedef指定子は適切にインライン化されますか?

クラスメンバー関数のC ++テンプレート定義を.Hの代わりにIMPLICITインスタンス化を使用してCPPファイルに配置できますか?

golangの文字列に従って異なる型をインスタンス化できますか?

同じテンプレート関数からのローカル静的変数によってパラメーター化されたテンプレートタイプは等しく比較する必要がありますか?

ラムダはテンプレート関数をインスタンス化できますか?

テンプレート関数またはクラス内の型を含むコンテナの変数をインスタンス化するにはどうすればよいですか?

Android admobは、アプリのUIに従ってネイティブアドバンス広告のレイアウトを再変更できますか

可変個引数クラステンプレートタイプのメンバー関数の結果で配列を初期化していますか?

テンプレートのインスタンスの関数へのアドレスを、関数へのポインターとして関数に渡すことはできますか?

コンパイル時にすべてのc ++テンプレートサイズをインスタンス化する方法はありますか?

関数テンプレートをインスタンス化するときにテンプレートタイプの引数を省略することは合法ですか?

デフォルトの引数が暗黙的に他のタイプに変換できないテンプレートの特殊化を明示的にインスタンス化できるのはなぜですか?

テンプレートクラスの関数定義で「this」ポインタを使用する-式には(ポインタから)関数型が必要です

Cコンパイラは未使用の関数の引数を最適化できますか?

C ++では、インスタンスをインスタンス化せずに、クラスのテンプレートに仮想デストラクタがあるかどうかをテストする(新しい)方法はありますか?

メンバー関数テンプレートのインスタンス化を削除するにはどうすればよいですか?

ランタイム入力に従ってc ++テンプレートをインスタンス化する方法は?

インデックス付きのベクトルに従ってソートするためのnumpy関数はありますか?

TOP 一覧

  1. 1

    グラフからテーブルに条件付き書式を適用するにはどうすればよいですか?

  2. 2

    ソートされた検索、ターゲット値未満の数をカウント

  3. 3

    Unity:未知のスクリプトをGameObject(カスタムエディター)に動的にアタッチする方法

  4. 4

    セレンのモデルダイアログからテキストを抽出するにはどうすればよいですか?

  5. 5

    Ansibleで複数行のシェルスクリプトを実行する方法

  6. 6

    Reactでclsxを使用する方法

  7. 7

    tkinterウィンドウを閉じてもPythonプログラムが終了しない

  8. 8

    Windows 10 Pro 1709を1803、1809、または1903に更新しますか?

  9. 9

    Pythonを使用して同じ列の同じ値の間の時差を取得する方法

  10. 10

    PowerShellの分割ファイルへのヘッダーの追加

  11. 11

    Chromeウェブアプリのウェブビューの高さの問題

  12. 12

    BLOBストレージからデータを読み取り、Azure関数アプリを使用してデータにアクセスする方法

  13. 13

    Crashlytics:コンパイラー生成とはどういう意味ですか?

  14. 14

    GoDaddyでのCKEditorとKCfinderの画像プレビュー

  15. 15

    Windows 10の起動時間:以前は20秒でしたが、現在は6〜8倍になっています

  16. 16

    MLでのデータ前処理の背後にある直感

  17. 17

    モーダルダイアログを自動的に閉じる-サーバーコードが完了したら、Googleスプレッドシートのダイアログを閉じます

  18. 18

    reCAPTCHA-エラーコード:ユーザーの応答を検証するときの「missing-input-response」、「missing-input-secret」(POSTの詳細がない)

  19. 19

    STSでループプロセス「クラスパス通知の送信」のループを停止する方法

  20. 20

    ファイル内の2つのマーカー間のテキストを、別のファイルのテキストのセクションに置き換えるにはどうすればよいですか?

  21. 21

    ネットワークグラフで、ネットワークコンポーネントにカーソルを合わせたときに、それらを強調表示するにはどうすればよいですか?

ホットタグ

アーカイブ