假设我需要做类似的事情:
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_template
是some_template
的可变版本,在哪里你可以提供从2到多个参数的任何地方?我的意思是我希望能够说:
mixin(another_template!("x", "foo", "bar", "baz"));
mixin(another_template!("y", "foo", "bar"));
mixin(another_template!("z", "baz"));
并将其扩展为与第一个示例扩展到的等效代码。
答案 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)
。
答案 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");