Вопрос
Недавно я экспериментировал с языком D, и у меня возник вопрос по поводу шаблонов.
Я вставляю символы и строки в существующую строку кода и придумал эту функцию:
string insert(T)(string s1, T s2, uint position) {
return s1[0 .. position] ~ s2 ~ s1[position .. $];
}
Теперь у меня есть несколько вопросов.
Могу ли я ограничить типы, разрешенные для аргумента s2 (мне нужны только char, wchar, dchar и т. д.и соответствующие им значения массива)?
Есть ли какой-нибудь способ определить шаблон, который автоматически будет знать, что его нужно добавлять, если аргумент позиции равен 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 .. $]; }
Спасибо
Решение
- Да, используя любой специализация параметров шаблона или ограничения шаблона (эквивалент концепций C++1x).
static if
подразумевает, что условие может быть вычислено во время компиляции.Параметром функции быть не может, поэтому либо используйте обычныйif
или сделатьposition
параметр шаблона.
Другие советы
Для 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
модуль должен сделать свое дело.
Что касается 2, не можете ли вы просто использовать обычный оператор if?