【问题标题】:D template specialization in different source file不同源文件中的 D 模板特化
【发布时间】:2011-06-15 18:10:42
【问题描述】:

我最近向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();
}

当我运行这段代码时,它会打印“通用”。所以我问是否有一些好的解决方法,以便可以从算法中使用更专业的形式。

我在关于类型类的问题中使用的解决方法是在导入所有具有模板专业化的文件后混合泛型函数,但这有点丑陋和有限。

我听说 c++1x 会有外部模板,这将允许这样做。 D有类似的特点吗?

【问题讨论】:

  • 这在很大程度上是不允许的,原因包括避免不必要的功能劫持,例如如果Generic 是私有的,那么template.d 不希望任何其他模板覆盖它可以做任意事情跨度>
  • 在specialization.d 中写“别名模板.Generic Generic”有帮助吗?这是强制功能劫持的方法d-programming-language.org/hijack.html

标签: templates d


【解决方案1】:

我想我可以对这个问题给出一个正确的答案。没有。

您正在尝试做的是劫持 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 试图劫持 getUserData

// specialization.d
import std.stdio;
import template;
import helper;

alias helper.getUserData getUserData;

string getUserData(int num) { ... }

void main() {
    testTemplate!int();
    getUserData();
}

【讨论】:

    【解决方案2】:

    IIRC;作为 D 中的一般事项,不同文件中的符号不​​能重载,因为符号的全名包括模块名称(文件名),使它们成为不同的符号。如果 2 个或更多符号具有相同的非限定名称并且来自 2 个或更多文件,则尝试使用该非限定符号将导致编译错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-01
      • 2014-06-25
      相关资源
      最近更新 更多