Некоторые вопросы шаблона D - PullRequest
6 голосов
/ 23 октября 2009

Я недавно поигрался с языком D, и у меня есть быстрый вопрос о шаблонах.

Я вставляю символы и строки в существующую строку в коде и придумал эту функцию:

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

Теперь у меня есть несколько вопросов.

  1. Могу ли я ограничить типы, разрешенные для аргумента s2 (я хочу только char, wchar, dchar и т. Д. И их соответствующие значения массива)?

  2. Есть ли какой-нибудь способ определить шаблон, чтобы автоматически знать, что нужно добавить, если позиция arg равна 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 .. $];
    }
    

Спасибо

Ответы [ 3 ]

4 голосов
/ 23 октября 2009
  1. Да - используя специализацию параметров шаблона или ограничения шаблона (эквивалент концепций C ++ 1x).
  2. static if подразумевает, что условие может быть вычислено во время компиляции. Параметр функции не может быть, поэтому либо используйте обычный if, либо сделайте position параметром шаблона.
1 голос
/ 24 октября 2009

Для 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

Другой - после выбора метода. Именно здесь компилятор уже решил использовать этот конкретный метод. Вы можете сделать это со статическими утверждениями. Обратите внимание, что это не заставляет компилятор работать так: «О, я должен попытаться найти другую перегрузку!»; это просто сдастся.

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);
    }
    ...
}

Еще одна вещь: насколько я знаю, вы ** не можете * просто объединить wchars и dchars в строку (которая является массивом символов). Сначала вам нужно будет закодировать символ в строку. encode в модуле std.utf должен добиться цели.

0 голосов
/ 23 октября 2009

Что касается 2, вы не можете просто использовать обычный оператор if?

...