我最近询问了this关于如何在D中模拟类型类的问题,并提出了一种使用模板特化来实现此目的的方法。
我发现D不能识别不同源文件中的模板特化。因此,我只能在未包含在定义泛型函数的文件中的文件中进行专门化。为了说明,请考虑以下示例:
//template.d
import std.stdio;
template Generic(A) {
void sayHello() {
writefln("Generic");
}
}
void testTemplate(A)() {
Generic!A.sayHello();
}
//specialization.d
import std.stdio;
import Template;
template Generic(A:int) {
void sayHello() {
writefln("only for ints");
}
}
void main() {
testTemplate!int();
}
此代码在运行时打印“generic”。所以我在问是否有一些好的解决方法,以便可以从算法中使用更专业的表格。
我在关于Type类的问题中使用的解决方法是在使用模板特化导入所有文件后混合泛型函数,但这有点难看且有限。
我听说c ++ 1x会有extern模板,这将允许这样做。 D有类似的功能吗?
答案 0 :(得分:5)
我想我可以对这个问题给出正确答案。否。
你要做的是劫持template.d的功能(也应该在文件上匹配并导入模板,一些操作系统很重要)。考虑:
// template.d
...
// spezialisation.d
import std.stdio;
import template;
void main() {
testTemplate!int();
}
现在有人更新了代码:
// specialization.d
import std.stdio;
import template;
import helper;
void main() {
testTemplate!int();
getUserData();
}
完美对吗?好帮手:
// helper.d
getUserData() { ... }
template Generic(A:int) {
A placeholder; //...
}
您现在已经从导入中更改了specialization.d的行为,实际上这将无法编译,因为它无法调用sayHello。这种劫持预防确实存在问题。例如,您可能有一个带有Range的函数,但是库的使用者无法传递数组,除非您的库导入std.array,因为这是将数组“转换”为范围的地方。
我没有针对您的问题的解决方法。
Michal的评论为第二种形式的劫持提供了解决方案,其中说specialization.d试图使用highjack getUserData
// specialization.d
import std.stdio;
import template;
import helper;
alias helper.getUserData getUserData;
string getUserData(int num) { ... }
void main() {
testTemplate!int();
getUserData();
}
答案 1 :(得分:0)
IIRC;作为D中的一般事项,不同文件中的符号不能重载,因为符号的全名包括模块名称(文件名),使它们成为不同的符号。如果2个或更多符号具有相同的非限定名称且来自2个或更多文件,则尝试使用该非限定符号将导致编译错误。