D中是否可以使用可变混合模板?

时间:2014-11-19 02:23:01

标签: templates d mixins variadic-templates

假设我需要做类似的事情:

mixin(some_template!("x", "foo"));

mixin(some_template!("x", "bar"));

mixin(some_template!("x", "baz"));

mixin(some_template!("y", "foo"));

mixin(some_template!("y", "bar"));

mixin(some_template!("z", "baz"));

以某种方式创建another_templatesome_template的可变版本,在哪里你可以提供从2到多个参数的任何地方?我的意思是我希望能够说:

mixin(another_template!("x", "foo", "bar", "baz"));

mixin(another_template!("y", "foo", "bar"));

mixin(another_template!("z", "baz"));

并将其扩展为与第一个示例扩展到的等效代码。

2 个答案:

答案 0 :(得分:7)

是的,使用常规可变参数模板语法(Something...收集给定的其余模板参数,它们可以是混合类型。请参阅:http://dlang.org/template#TemplateTupleParameter):

string some_template(strings...)() {
        string a;
        foreach(f; strings)
                a ~= f;
        return a;
}

void main() {
        mixin(some_template!("int ", "giggle", ";"));
}

您可以使用以下约束来限制类型:

// this condition will only compile if it is passed a string
import std.typetuple;
enum check_if_string(string s) = true;

// then we check that they all compile with the check_if_string check
string some_template(strings...)() if(allSatisfy!(check_if_string, strings)) {
        string a;
        foreach(f; strings)
                a ~= f;
        return a;
}

错误信息会很难看,即使没有这个检查,非字符串也不会编译,所以它并不重要。但您也可以使用if检查,例如if(strings.length >= 2)

这称为模板约束:http://dlang.org/template#Constraint

答案 1 :(得分:5)

这个答案假设你真的是template mixins,而不是模板化的函数。

是的,您可以声明可变参数模板参数,例如:

mixin template another_template(string A, Bs...)

然后,您可以使用static if和递归实例化来处理整个列表。

完整示例:

mixin template some_template(string A, string B)
{
    pragma(msg, "some_template: " ~ A ~ ", " ~ B);
}

mixin template another_template(string A, Bs...)
{
    mixin some_template!(A, Bs[0]);
    static if (Bs.length > 1)
        mixin another_template!(A, Bs[1..$]);
}

mixin another_template!("x", "foo", "bar", "baz");

mixin another_template!("y", "foo", "bar");

mixin another_template!("z", "baz");