Если вы не хотите ограничивать шаблон оператором 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.