D 表达式是否忽略不可变/常量?

D 表达式是否忽略不可变/常量?,d,dmd,D,Dmd,我正在使用函数模板void\u createAttr(T)(args…,在T[])并在函数中使用static if(is(T==char))测试T的类型。当我打电话时 _createAttr!char(args...,"someString") _createAttr(args...,"someString") 编译器从不抱怨 当然我知道,alias string=immutable(char)[。因此,在第一个调用中,T的类型和提供的参数不匹配,但是中的修饰符应该解决这个问题。在第二种情况下

我正在使用函数模板
void\u createAttr(T)(args…,在T[])
并在函数中使用
static if(is(T==char))
测试
T
的类型。当我打电话时

_createAttr!char(args...,"someString")
_createAttr(args...,"someString")
编译器从不抱怨

当然我知道,
alias string=immutable(char)[
。因此,在第一个调用中,T的类型和提供的参数不匹配,但是中的
修饰符应该解决这个问题。在第二种情况下,它应该推断
T=immutable(char)
。据我所知,
immutable(char)
char
是不同的类型,但是编译器在第二种情况下通过了is测试

在进行is测试时,编译器(DMD)似乎忽略了字符串中字符的不可变性

我在dlang.org或D编程语言书中找不到关于这种行为的任何解释


这是一个编译器错误吗?

没有错误,它只是扩展到
const
限定符中的
,它对
不可变(char)
char
都同样有效,因此编译器只实例化它一次

如果
T==char
,那么T[]
中的
意味着
const char[]
涵盖了这两种情况,因此模板不需要考虑不变性。您还可以向该函数传递可变字符串,而不会出现任何问题


如果您明确地执行了
!(immutable(char))
那么它将使用它,而不再接受可变的。

那么,如果我在函数参数列表的
限定符中放入一个
,它也将应用于模板参数列表?这让人困惑。不,它只适用于函数参数,但由于在第二种情况下自动推导出T,所以模板参数是通过查看函数参数计算出来的。如果您手工编写该函数,通常会编写
const char[]
,因此,由于您编写了
const T[]
,编译器只需将
T
作为
char
进行填充。编译器对数组和模板执行一些特殊的操作(就像剥离
const
的外层一样,因为它知道数组传入时将被切片),因此当编译器使用
T[]
推断T的类型时,比仅仅使用
T
更容易让您感到惊讶。它最终更方便用户(例如,
const
的外层没有被剥离,这非常烦人),因此我们最好还是这样做,但有时会令人惊讶。