2014-12-03 3 views
3

Как бы написать шаблон ограничения для следующей структурыD: Шаблон ограничения, чтобы показать, является ли сопоставим данный тип

struct Foo (T, U) { 
} 

, чтобы указать, что оба T и U должны быть сравнимы с использованием <? Под этим я подразумеваю, что два T s можно сравнить с <, а два U s можно сравнить с < - a T и U могут быть несравнимыми.

ответ

7

Я считаю, что это будет делать то, что вы спрашиваете, хотя может быть более кратким решением:

struct Foo (T, U) if (is(typeof(T.init < T.init) : bool) 
        && is(typeof(U.init < U.init) : bool) 
{ } 

Вы можете очистить его немного с шаблоном:

enum bool isSelfComparable(T) = is(typeof(T.init < T.init) : bool); 

struct Foo (T, U) if (isSelfComparable!T && isSelfComparable!U) { } 
2

Наиболее кратким так, что я могу думать о том, что делать в данный момент

struct Foo(T, U) 
    if(is(typeof(T[0] < T[0])) && is(typeof(U[0] < U[0]))) 
{ 
} 

, но я бы, вероятно, объявить его как

struct Foo(T, U) 
    if(is(typeof(T.init < T.init)) && is(typeof(U.init < U.init))) 
{ 
} 

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

: bool часть в murphyslaw's answer на самом деле не нужно, потому что < не может привести ни к чему, кроме bool, потому что компилятор переводит <, <=, > и >= на вызовы opCmp на определяемые пользователем типы, поэтому программист не имеет возможности сделать их результатом чего угодно, кроме bool (и, конечно, операторы сравнения приводят к bool для встроенных типов). Но murphyslaw's answer будет работать так же хорошо. Это просто более подробный, чем требуется.

Основное место, которое : bool или == bool потребовалось бы если бы вы хотели, чтобы принять предикат, а не использовать операторы сравнения непосредственно (с тех пор, вы имеете дело с произвольной функцией), и это обычно то, что общий алгоритмы в Phobos в конечном итоге делают. например подпись одного из перегрузок find «s является

InputRange find(alias pred = "a == b", InputRange, Element) 
       (InputRange haystack, Element needle) 
    if (isInputRange!InputRange && 
     is (typeof(binaryFun!pred(haystack.front, needle)) : bool)) 
{...} 

Но если вы планируете использовать операторы сравнения непосредственно, а затем просто проверить, что они компилировать достаточно.

Смежные вопросы