8

私はD言語のテンプレートシステムについて読んでいて、珍しい構成に出くわしましたstatic if

私が何とか把握したことから、コンパイル時に評価されますが、私が検索したことから、ここに示されている例は私を完全に啓発しませんでした。

template Factorial(ulong n)
{
    static if(n < 2)
        const Factorial = 1;
    else
        const Factorial = n * Factorial!(n - 1);
}

何をしstatic ifますか、いつ使用する必要がありますか?

4

4 に答える 4

13

Dstatic ifは「条件付きコンパイル」のベースであり、コードのバリアントに関するコンパイル時の決定を行う必要がある場合は常に重要な役割を果たします。

Dにはプリプロセッサがないので、

#ifdef xxx
compile_this_piece_of_code
#endif

になることができる

static if(xxx)
{
     compile_this_pece_of_code
}

同様に、メタプログラミングは、次の場合にも静的を介して発生する可能性があります。

template<int x>
struct traits
{ some definition calculated from x };

template<>
struct traits<0>
{ same definitions for the 0 particular case }

することができます

template(int x)
{
    static if(x==0)
    { some definitions }
    else
    { some other same definitions }
    even more definition common in the two cases
}
于 2012-09-11T12:54:56.173 に答える
4

ウィキペディアの例は実際には非常に単純です。

template Factorial(ulong n)
{
    static if(n < 2)
        const Factorial = 1;
    else
        const Factorial = n * Factorial!(n - 1);
}

これは同名のテンプレートです(以下のJonathanのコメントを参照してください)。nテンプレートパラメータです。したがって、代わりに次のように書いた場合はどうなりますか。

template Factorial(ulong n)
{
    if(n < 2) // NOTE: no static here
        const Factorial = 1;
    else
        const Factorial = n * Factorial!(n - 1);
}

?- うまくいかないだろう。http://dpaste.dzfl.pl/3fe074f2を確認してください。その理由は、静的な場合と「通常」の場合のセマンティクスが異なるという事実です。コンパイル時static ifに評価される代入式(http://dlang.org/version.html、セクション「静的If」)を取りますが、通常の場合は実行時に評価される式を取ります。

Static ifEmilioが言及した「条件付きコンパイル」を実行する1つの方法にすぎません。Dにもversionキーワードがあります。したがって、Emilioの最初の条件付きコンパイルの例(Dでは機能しません)は次のようになります。

version (XXX) { 
    // XXX defined 
} else { 
    // XXX not defined 
}

このために静的を使用したい場合は、次のように記述します。

enum int XXX = 10;
static if (XXX == 10) {
    pragma(msg, "ten");
}
于 2012-09-11T13:03:15.567 に答える
3

Andrei Alexandrescuは、C ++コンテキストの場合、静的についてここで見ることができる良い話をしています(それがあなたの求めているものである場合)。

リンク:http ://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Static-If-I-Had-a-Hammer

簡単な答え-それはいくつかのテンプレートメタプログラミングの構文をはるかに直感的にします。

于 2012-09-11T15:03:48.733 に答える
0

アンドレイ・アレキサンドレスクは最近static if、いくつかの素晴らしい例(ビデオスライド)とともに、「内省によるデザイン」の賢い使用法を呼びかけています。

彼の講演の直接的な例は、Robin Hoodハッシュを使用したハッシュテーブルなどの汎用コンテナの実装です。この場合、テーブルの各エントリに追加のデータ(プローブ数)が保持されます。を使用static ifすると、位置合わせに基づいてキーの横にプローブカウントを配置したり、インデックスタイプの整数幅を最適化したりすることで、メモリを自動的に最適化できます。

話から言い換えると:

struct RobinHashTable(K, V, size_t maxLength) {
  static if (maxLength < ushort.max-1) {
    alias CellIdx = ushort;
  } else {
    alias CellIdx = uint;
  }

  static if (K.sizeof % 8 < 7) {
    align(8) struct KV {
      align(1):
        K k;
        ubyte cellData;
      align(8):
        V v;
    }
  } else {
    align(8) struct KV {
      align(8):
        K k;
        V v;
      align(1):
        ubyte cellData;
    }
  }
}
于 2017-08-01T09:30:30.243 に答える