Некоторые вопросы по шаблону D

Недавно я играл с языком 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 .. $];
    }
    

Спасибо


person GKelly    schedule 23.10.2009    source источник
comment
StackOverflow считает, что ваш второй блок кода является новым абзацем для пункта 2.   -  person he_the_great    schedule 24.10.2009


Ответы (3)


  1. Да, используя либо специализацию параметра шаблона, либо ограничения шаблона (эквивалент концепций C++1x).
  2. static if означает, что условие может быть вычислено во время компиляции. Параметром функции быть не может, поэтому либо используйте обычный if, либо сделайте position параметром шаблона.
person Vladimir Panteleev    schedule 23.10.2009
comment
Как вы собираетесь сделать «позицию» параметром шаблона? Что-то вроде следующего? string insert(T, uint Position)(...) { static if (Position == 0) ... else ... } - person GKelly; 28.10.2009
comment
По сути, я ищу способ избежать как можно большего количества решений во время выполнения, поэтому я пытаюсь понять, смогу ли я избежать «нормального» если. Честно говоря, я просто изучаю язык, обычно я был бы достаточно нестатичен, если бы, но я просто изучаю, что возможно. - person GKelly; 28.10.2009

Для 1 на самом деле есть два места, где вы можете ограничить допустимые типы.

Первый — до выбора метода. Если символ разрешается в несколько методов, компилятор попытается удалить столько, сколько сможет, прежде чем он попытается решить, какой из них использовать. На этом этапе работают ограничения шаблона (только D2) и специализация. Например:

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

-or-

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 должно помочь.

person DK.    schedule 24.10.2009

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

person Bernard    schedule 23.10.2009