6

最近 D 言語をいじっていて、テンプレートについて簡単な質問があります。

コード内の既存の文字列に文字と文字列を挿入していて、この関数を思いつきました:

string insert(T)(string s1, T s2, uint position) {
    return s1[0 .. position] ~ s2 ~ s1[position .. $];
}

さて、いくつか質問があります。

  1. s2 引数に使用できる型を制限できますか (char、wchar、dchar などとそれぞれの配列値のみが必要です)。

  2. 位置引数が0の場合に先頭に追加することを自動的に認識するようにテンプレートを定義する方法はありますか? このようなもの(コンパイルはしませんが、一般的なアイデアを提供します):

    string insert(T)(string s1, T s2, uint position) {
      static if (position == 0)
        return "" ~ s2 ~ s1;
      else
        return s1[0 .. position] ~ s2 ~ s1[position .. $];
    }
    

ありがとう

4

3 に答える 3

4
  1. はい -テンプレート パラメーターの特殊化またはテンプレートの制約(C++1x の概念と同等) のいずれかを使用します。
  2. static ifコンパイル時に条件を計算できることを意味します。関数パラメーターは使用できないため、通常のパラメーターを使用するかifpositionテンプレート パラメーターを作成してください。
于 2009-10-23T15:47:03.077 に答える
1

1 の場合、許容される型を制限できる場所が実際には 2 つあります。

1つ目は方法選択前です。シンボルが複数のメソッドに解決される場合、コンパイラは、使用するメソッドを決定する前に、できるだけ多くのメソッドを削除しようとします。テンプレートの制約 (D2 のみ) と特殊化は、このフェーズで機能します。例えば:

string insert(T)(string s1, T s2, uint position) if(isSomeChar!T) // D2 only

-また-

string insert(T : dchar)(string s1, T s2, uint position) // D1 or D2

もう 1 つはメソッドの選択後です。これは、コンパイラがこの特定のメソッドを使用することを既に決定している場所です。これは、静的アサートで行うことができます。これにより、コンパイラが「ああ、別のオーバーロードを探す必要があります!」となるわけではないことに注意してください。それは単にあきらめます。

string insert(T)(string s1, T s2, uint position)
{
    static if( !isSomeChar!(T) )
    {
        pragma(msg, "Error: insert(T): T must be a character type.");
        static assert(false);
    }
    ...
}

もう 1 つ: 私の知る限り、単純に wchar と dchar を連結して文字列 (文字の配列) にすることは **できません*。まず、文字を文字列にエンコードする必要があります。 モジュールでトリックを行う必要がありますencodestd.utf

于 2009-10-24T03:46:08.820 に答える
0

2については、普通のif文でいいんじゃないの?

于 2009-10-23T15:04:03.523 に答える