【问题标题】:d2: Immutable structs with opApply do not compile when initialized with non-default constructord2:具有 opApply 的不可变结构在使用非默认构造函数初始化时不会编译
【发布时间】:2012-04-24 10:53:26
【问题描述】:

考虑以下代码:

immutable struct Test {
    this(int foo) { }

    int opApply(int delegate(ref int) dg) {
        return (0);
    }
}

int main(string[] argv) {
    auto set = Test(); // compiles
    // auto set = Test(1); // Error: cannot uniquely infer foreach argument types

    foreach (item; set) { }

    return 0;
}

Test 结构使用默认的无参数构造函数构建时,代码编译得很好,但是当我尝试使用任何其他构造函数时,我得到编译时错误。如果我注释掉foreach,代码将编译。如果我注释掉immutable,代码也会编译。

这种行为的原因是什么,应该如何解决?

【问题讨论】:

    标签: foreach immutability d


    【解决方案1】:

    实际上,至少在使用 DMD 2.059 版时,它不能使用任一构造函数进行编译(在 Windows 7 和 FreeBSD 上测试)。

    这样做的原因应该是相当明显的。通过使结构(或类)不可变,您只需将不可变应用于该结构(或类)的每个成员。但是,构造函数不会变得不可变。也就是说,当您声明 immutable struct Test 时,您实际上已经完成了以下操作:

    struct Test {
        this(int foo) { }
        immutable int opApply(int delegate(ref int) dg) {
            return (0);
        }
    }
    

    注释掉 foreach 循环允许代码编译,因为 foreach 正在寻找一个没有 immutable 声明的 opApply 方法。

    根据您要执行的操作,您可以简单地使结构 final 而不是 immutable,或者,如果您想保持大部分结构不可变...

    struct Test {
        // Anything that needs to be mutable should go up here
        int opApply(int delegate(ref uint) dg) {
            return 0;
        }
    
        // Anything put in this block is immutable
        immutable {
            this(int foo) { }
        }
    }
    

    【讨论】:

    • 你是对的,除了 immutable struct 暗示 immutable this(int foo) { }。似乎不可变结构中的构造函数仍然是可变的,因此显式指定 this(int foo) immutable {} 足以解决此冲突,然后代码就可以工作了。不过,感谢您帮助我解决这个问题。
    • 哦,你说得对,我完全错过了。您提交错误报告是正确的。我将编辑我的答案以适应这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    相关资源
    最近更新 更多