Reputation: 7480
Consider following code:
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;
}
When Test
structure is built using default no-argument constructor, code compiles fine, but when I try to use any other constuctor, I get compile time error. If I comment out foreach
, code will compile. If I comment out immutable
, code will compile too.
What is the reason for this kind of behavior and how it should be fixed?
Upvotes: 1
Views: 135
Reputation: 48
Actually, at least using DMD version 2.059, it doesn't compile (tested on Windows 7 and FreeBSD) with either constructor.
The reason for this ought to be fairly obvious. By making a struct (or class) immutable, you are simply applying immutable to every member of that struct (or class). However, the constructors do not become immutable. That is, when when you declare immutable struct Test
you have effectively done the following:
struct Test {
this(int foo) { }
immutable int opApply(int delegate(ref int) dg) {
return (0);
}
}
Commenting out the foreach loop allows the code to compile because foreach is looking for an opApply method without the immutable
declaration.
Depending on what you're trying to do, you could simply make the struct final
instead of immutable
, or, if you want to keep most of your struct 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) { }
}
}
Upvotes: 3