变量模板函数,参数全部相同

时间:2013-09-07 11:29:33

标签: d template-specialization variadic-functions lvalue

如何限制可变参数模板化函数强制其参数属于同一类型?

我需要这个专业化

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作为返回类型转发l值。一路上的东西

auto ref either(T...

应该满足

unittest {
    int x = 1, y = 2;
    either(x, y) = 3;
    assert(x == 3);
}

这允许通过逻辑eitherevery(未显示)转发值,类似于Lisps的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的两个版本的正文是相同的。这似乎是不必要的。 mixin是删除此冗余的最佳方法吗?

2 个答案:

答案 0 :(得分:3)

您需要编写一个模板来确定类型元组中的所有类型是否相同:

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 && allSame!T)

答案 1 :(得分:3)

关于您的allSame模板,您还可以使用allSatisfy中的std.typetuple

import std.typetuple;

/** Returns: true if all types T are the same. */
template allSame(T...) {

    template isType(X) { enum bool isType = is(X == T[0]); }
    enum bool allSame = allSatisfy!(isType, T);
}

void main()
{
    static assert(!allSame!(int, float, string));
    static assert(allSame!(int, int, int));
    static assert(allSame!(int));
}