3

如何限制可变参数模板化函数以强制其参数全部为同一类型?

我需要这个来专业化

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

auto ref either(T...

应该满足

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

either这允许通过逻辑和(未显示)转发值,every类似于 Lisps 的and()or()

这将使那些喜欢 D 的人能够更强大地使用 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是相同的。这似乎是不必要的。混合是消除这种冗余的最佳方法吗?

4

2 回答 2

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)
于 2013-09-07T11:49:28.473 回答
3

关于您的allSame模板,您还可以使用allSatisfyfrom 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));
}
于 2013-09-07T15:15:27.307 回答