D template specialization in different source file

懵懂的女人 提交于 2019-12-23 07:36:46

问题


I recently asked this question about how to simulate type classes in D and suggested a way to do this using template specialization.

I discovered that D doesn´t recognize template specialization in a different source file. So I couldn´t just make a specialization in a file not included from the file where the generic function is defined. To illustrate, consider this example:

//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();
}

This code prints "generic" when I run it. So I´m asking whether there is some good workaround, so that the more specialized form can be used from the algorithm.

The workaround I used in the question about Type classes was to mixin the generic functions after importing all files with template specialization, but this is somewhat ugly and limited.

I heard c++1x will have extern templates, which will allow this. Does D have a similar feature?


回答1:


I think I can give a proper answer to this question. No.

What you are trying to do is highjack the functionality of template.d (also case should match on file and import Template, some operating systems it matters). Consider:

// template.d
...

// spezialisation.d
import std.stdio;
import template;

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

Now someone updates the code:

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

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

Perfect right? well inside helper:

// helper.d
getUserData() { ... }


template Generic(A:int) {
    A placeholder; //...
}

You have now changed the behavior of specialization.d just from an import and in fact this would fail to compile as it can not call sayHello. This highjack prevention does have its issues. For example you may have a function which takes a Range, but the consumer of your library can not pass an array unless your library imports std.array since this is where an array is "transformed" into a range.

I do not have a workaround for your problem.

Michal's comment provides a solution to the second form of highjacking, where say specialization.d tried to highjack 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; as a general matter in D, symbols in different files can't overload because the full name of a symbol includes the module name (file name) making them different symbols. If 2 or more symbols have the same unqualified name and are from 2 or more files, attempting to use that unqualified symbol will result in a compile error.



来源:https://stackoverflow.com/questions/6362280/d-template-specialization-in-different-source-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!