接口模板作为函数参数的语法:如何避免限定模板类型?
解决方案:用模板函数自动推导类型参数
当然可以啦!在D语言里,你只需要把函数定义成模板函数,让编译器自动推导模板接口的类型参数T就行,完全不用在函数签名里写死具体的类型。
具体实现方式
直接把函数声明为模板函数,参数类型指定为TemplateInterface!T,编译器会根据你传入的实参自动推断出T的具体类型:
// 定义模板接口 interface TemplateInterface(T) { T x(); } // 通用函数:自动推导T的类型 void func(T)(TemplateInterface!T parm1) { // 可以正常调用接口方法,返回值类型为T auto value = parm1.x(); import std.stdio; writeln("获取到的值:", value); }
使用示例
我们定义两个实现该接口的类,分别对应不同的T类型,然后直接传入func即可:
class IntImpl : TemplateInterface!int { int x() { return 42; } } class StringImpl : TemplateInterface!string { string x() { return "Hello D!"; } } void main() { auto intObj = new IntImpl(); auto strObj = new StringImpl(); func(intObj); // 编译器自动推导T=int func(strObj); // 编译器自动推导T=string }
运行这段代码会输出:
获取到的值:42 获取到的值:Hello D!
原理说明
这里的func是一个模板函数,参数类型TemplateInterface!T会告诉编译器:“这个参数必须是TemplateInterface接口的某个实例化类型”,编译器在调用函数时会根据传入的对象自动确定T的具体值,从而实现了“接受任意传入的模板类型”的需求,完全不用在函数签名里限定死int或者其他具体类型。
如果你需要更严格的类型约束(比如确保参数确实是TemplateInterface的实例),还可以用isInstanceOf模板来添加约束:
void func(T)(auto ref parm1) if (isInstanceOf!(TemplateInterface, typeof(parm1))) { auto value = parm1.x(); // ... 逻辑代码 }
不过第一种写法已经足够简洁,因为参数类型本身就隐含了约束,编译器会自动检查传入的参数是否符合要求。
内容的提问来源于stack exchange,提问作者Aaron Thomas
相关产品推荐
相关产品推荐

