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

Koz*_*oss 4 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"));
Run Code Online (Sandbox Code Playgroud)

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

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

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

mixin(another_template!("z", "baz"));
Run Code Online (Sandbox Code Playgroud)

并将它扩展到与第一个示例扩展到的等效代码.

Ada*_*ppe 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", ";"));
}
Run Code Online (Sandbox Code Playgroud)

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

// 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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


Vla*_*eev 5

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

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

mixin template another_template(string A, Bs...)
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用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");
Run Code Online (Sandbox Code Playgroud)