Foreach d2:使用非默认构造函数初始化时,不编译带有opApply的不可变结构

Foreach d2:使用非默认构造函数初始化时,不编译带有opApply的不可变结构,foreach,immutability,d,Foreach,Immutability,D,考虑以下代码: 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 fo

考虑以下代码:

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的
,代码将编译。如果我把
不可变的
注释掉,代码也会编译


这种行为的原因是什么?应该如何修复?

事实上,至少在使用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正在寻找一个没有
不可变
声明的opApply方法

根据您尝试执行的操作,您可以简单地将结构
设置为final
,而不是
不可变
,或者,如果您想保持大部分结构不可变

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) { }
    }
}

你是对的,除了
不可变结构
意味着
不可变这个(intfoo){}
。看起来不可变结构中的构造函数仍然是可变的,所以显式地指定
this(intfoo)immutable{}
就足以解决这个冲突,然后代码就可以工作了。不过,谢谢你帮我解决这个问题。哦,你说得对,我完全错过了。你提交错误报告是正确的。我将编辑我的答案以适应这一点。