2015-07-14 3 views
3

Я использую шаблон функции void _createAttr(T)(args..., in T[]) и проверяю тип T с static if(is(T == char)) в функции. Когда я звоню,- выражение игнорирует неизменяемый/const?

_createAttr!char(args...,"someString") 
_createAttr(args...,"someString") 

компилятор никогда не жалуется.

Конечно, я знаю это alias string = immutable(char)[]. Таким образом, в первом вызове тип T и поставленный аргумент не совпадают, но модификатор in должен позаботиться об этом. А во втором случае следует сделать вывод T = immutable(char). Как я понимаю, immutable(char) и char - это разные типы, но компилятор передает тест во втором случае.

Компилятор (DMD), кажется, игнорирует неизменность символов в строке при выполнении теста.

Я не мог найти объяснения этого поведения на dlang.org или в книге D Programming Language.

Является ли это ошибкой компилятора?

ответ

4

Нет ошибка, это просто in классификатор расширяется до const, который в равной степени применимо как для immutable(char) и char, так что компилятор только конкретизирует это один раз.

Если T == char, то in T[] означает const char[], который охватывает оба случая, поэтому шаблону никогда не нужно думать о неизменности. Вы также можете передать изменчивую строку этой функции без каких-либо проблем.

Если вы явно сделали !(immutable(char)), тогда он будет использовать это и больше не будет принимать измененный.

+0

Итак, если я помещаю в список аргументов аргумент 'in', он также применяется к списку параметров шаблона? Это сбивает с толку. – Ryan

+1

Нет, это применимо только к параметру функции, но поскольку вы вывели T автоматически во втором случае, параметр шаблона вычисляется, просматривая параметр функции. Если вы пишете эту функцию вручную, вы обычно пишете 'const char []', поэтому, поскольку вы написали 'const T []', компилятор просто заполняет 'T' как' char'. –

+0

Компилятор делает несколько особых вещей с массивами и шаблонами (например, разделите внешний слой 'const', так как он знает, что массив будет нарезан при его передаче), поэтому, когда компилятор выводит тип T с 'T []', это гораздо больше удивит вас, чем если вы просто используете 'T'. В конечном счете, это более удобно для пользователя, как это было (например, было очень неприятно, когда этот внешний слой 'const' не был разделен), поэтому нам лучше для него, но это может быть неожиданно. –