问题描述
|
我最近问了一个有关如何在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有类似的功能吗?
解决方法
我想我可以给这个问题一个适当的答案。没有。
您要尝试做的是劫持template.d的功能(大小写也应在文件上匹配并导入Template,这对某些操作系统很重要)。考虑:
// 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试图劫持getUserData
// specialization.d
import std.stdio;
import template;
import helper;
alias helper.getUserData getUserData;
string getUserData(int num) { ... }
void main() {
testTemplate!int();
getUserData();
}
, IIRC;作为D中的一般问题,不同文件中的符号不会过载,因为符号的全名包括使它们成为不同符号的模块名称(文件名)。如果2个或更多符号具有相同的不合格名称,并且来自2个或更多文件,则尝试使用该不合格符号将导致编译错误。