Специализировать параметр шаблона для реализации 2 интерфейсов в D? - PullRequest
2 голосов
/ 21 августа 2010
interface I1 { ... }
interface I2 { ... }
struct List(T) { ... }

Как мне специализировать мой Список для работы только с классами, которые реализуют и I1 и I2? Один интерфейс прост:

struct List(T : I1)

Другие языки. В C # это:

struct List<T> where T : I1, I2

А на Яве я бы сказал:

class List<T extends I1 & I2>

Одна загвоздка: я не хочу шаблонное ограничение , если , потому что я хочу разумное автоматическое завершение из не-современных технологий. Я думаю, что пройдет много времени, прежде чем IDE для D сделают такие вещи, как обратное проектирование ограничений шаблонов, чтобы вывести список возможных методов T. И даже если это не похоже на дешевую производительность.

Ответы [ 2 ]

3 голосов
/ 21 августа 2010

Если вы не хотите ограничивать шаблон оператором if, единственный способ таков:

struct List(T : I1, U : I2 = T) {  }

, что означает, что вы можете создавать экземпляр List с одним или двумя аргументами, если вы создаете экземпляр только с одним -List! (C), тогда U будет по умолчанию присвоено значение C и проверено, реализует ли оно I2.Затем вы можете игнорировать параметр U в структуре.Проблема этого метода заключается в том, что вы создаете экземпляр List с двумя параметрами - List! (C1, C2) ...

Вот версия с ограничением if, которая не имеет этой проблемы:

struct List2(T) if ( is(T : I1) && is(T : I2)) {  }

Нет практического снижения производительности при использовании ограничения шаблона или любого метода времени компиляции, если вы не вычисляете много данных (например, ct raytracer или справочные таблицы)

Я бы действительнопредлагаем вам не ограничивать свой код тем, что поддерживает IDE - наверняка будет много вещей, которые ваша IDE не поддерживает хорошо, и вы можете оказаться гораздо менее веселыми, чем использовать простой текстовый редактор с подсветкой только синтаксиса, но с полным потенциаломD.

2 голосов
/ 21 августа 2010

В D2 вы можете использовать шаблонные ограничения и выражение is.

struct List(T)
   if (is(T : I1) && is(T : I2))
{
   ...
}

Здесь выражения is проверяют, является ли T неявно преобразуется в I1 и I2 (что возможно, только если T реализует их).

...