Как да огранича шаблонна функция с различни варианти, така че всички нейни аргументи да бъдат от един и същи тип?
Имам нужда от това за специализация на
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()
на Lisps.
Това би позволило още по-мощно използване на функционални конструкции в 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
е идентично. Това изглежда ненужно. Mixin най-добрият начин ли е да се премахне това излишък?