D шаблон специализации в другом исходном файле - PullRequest
9 голосов
/ 15 июня 2011

Я недавно задал этот вопрос о том, как имитировать классы типов в 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();
}

Этот код печатает «универсальный», когда я его запускаю. Поэтому я спрашиваю, есть ли хороший обходной путь, чтобы из алгоритма можно было использовать более специализированную форму.

Обходной путь, который я использовал в вопросе о классах Type, заключался в смешивании универсальных функций после импорта всех файлов со специализацией шаблонов, но это несколько уродливо и ограниченно.

Я слышал, что в c ++ 1x будут внешние шаблоны, которые позволят это. У D есть подобная особенность?

Ответы [ 2 ]

5 голосов
/ 16 июня 2011

Я думаю, что могу дать правильный ответ на этот вопрос. Нет.

То, что вы пытаетесь сделать, это перехватить функциональность 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, так как именно здесь массив «преобразован» в диапазон.

У меня нет решения для вашей проблемы.

Комментарий Михала предлагает решение второй формы хай-джэкинга, где, скажем, 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();
}
0 голосов
/ 28 июня 2011

IIRC;Как правило, символы D не могут перегружать символы в разных файлах, поскольку полное имя символа включает в себя имя модуля (имя файла), делающее их различными символами.Если 2 или более символов имеют одно и то же неквалифицированное имя и принадлежат к 2 или более файлам, попытка использовать этот неквалифицированный символ приведет к ошибке компиляции.

...