Как ограничить шаблонную функцию с переменным числом аргументов, чтобы все ее аргументы были одного типа?
Мне нужно это для специализации
CommonType!T either(T...)(T a) if (a.length >= 1)
{
static if (T.length == 1)
return a[0];
else
return a[0] ? a[0] : either(a[1 .. $]);
}
который может пересылать l-значения, используя auto ref
в качестве возвращаемого типа. Что-то по пути
auto ref either(T...
это должно удовлетворить
unittest {
int x = 1, y = 2;
either(x, y) = 3;
assert(x == 3);
}
Это позволяет передавать значения через логические схемы either
и every
(не показаны), аналогичные and()
и or()
в Лиспе.
Это позволит еще более эффективно использовать функциональные конструкции в D для тех, кто предпочитает его.
Обновить
Я считаю, что нашел рабочее решение:
/** Returns: true if all types T are the same. */
template allSame(T...) {
static if (T.length <= 1) {
enum bool allSame = true;
} else {
enum bool allSame = is(T[0] == T[1]) && allSame!(T[1..$]);
}
}
CommonType!T either(T...)(T a) if (a.length >= 1) {
static if (T.length == 1) {
return a[0];
} else {
return a[0] ? a[0] : either(a[1 .. $]);
}
}
auto ref either(T...)(ref T a) if (a.length >= 1 && allSame!T) {
static if (T.length == 1) {
return a[0];
} else {
return a[0] ? a[0] : either(a[1 .. $]);
}
}
alias either or;
Однако тело двух версий either
идентично. Это кажется ненужным. Является ли миксин лучшим способом устранить эту избыточность?