【问题标题】:is expression ignores immutable/const?表达式是否忽略不可变/常量?
【发布时间】:2015-07-14 04:07:14
【问题描述】:

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

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

编译器从不抱怨。

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

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

我在 dlang.org 或 The D Programming Language 书籍中找不到此行为的任何解释。

这是编译器错误吗?

【问题讨论】:

    标签: d dmd


    【解决方案1】:

    没有错误,它只是将in 限定符扩展为const,这对immutable(char)char 同样有效,因此编译器只实例化一次。

    如果T == char,那么in T[] 表示const char[],它涵盖了这两种情况,因此模板永远不需要考虑不变性。您也可以毫无问题地将可变字符串传递给该函数。

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

    【讨论】:

    • 那么如果我在函数参数列表中放置一个in 限定符,它是否也适用于模板参数列表?这令人困惑。
    • 不,它只适用于函数参数,但是由于你在第二种情况下自动推导出了T,所以模板参数是通过查看函数参数来计算的。如果您手动编写该函数,您通常会编写const char[],因此由于您编写了const T[],编译器只需将T 填写为char
    • 编译器确实对数组和模板做了一些特殊的事情(比如剥离const的外层,因为它知道数组在传入时会被切片),所以当编译器用T[] 推断T 的类型,这比只使用T 更有可能让你感到惊讶。它最终对用户更加友好(例如,当const 的外层没有被剥离时,它非常很烦人),所以我们对此更好,但它可以有时会令人惊讶。
    猜你喜欢
    • 2017-08-20
    • 2020-06-13
    • 2017-03-30
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多