January 14, 2018 variable template question | ||||
---|---|---|---|---|
| ||||
vartmpl.d ``` import std.stdio : writeln; import decimal : decimal32; template F(T) { immutable T c = 3; } void foo (T) () { immutable T t = 1; } void main () { // immutable decimal32 i = 1; // Error: none of the overloads of '__ctor' are callable using a immutable object // foo!decimal32; // Error: none of the overloads of '__ctor' are callable us ing a immutable object, candidates are: alias c = F!decimal32.c; c.writeln; writeln (typeof (c).stringof); } ``` $ dmd -g vartmpl.d decimal.git/libdecimal.a $ ./vartmpl 3 immutable(Decimal!32) Why does this compile while both of the commented lines give a compile error. decimal ist http://rumbu13.github.io/decimal/ |
January 14, 2018 Re: variable template question | ||||
---|---|---|---|---|
| ||||
Posted in reply to kdevel | On Sunday, 14 January 2018 at 16:23:18 UTC, kdevel wrote:
> Why does this compile while both of the commented lines give a compile error.
The code boils down to this:
----
struct decimal32
{
this(int x) {}
}
immutable decimal32 c = 3; /* works */
void main ()
{
immutable decimal32 i = 1; /* error */
}
----
I think this is CTFE being unexpectedly smart.
If you add the `pure` attribute to the constructor, then the `i` line works as well. That's because a strongly pure constructor is guaranteed to return a unique object, and a unique object can be converted implicitly to other mutability levels.
The `pure` attribute is needed for `i`, because here the compiler only looks at the function attributes to determine purity. No `pure` attribute -> function is regarded as impure.
But for `c`, the constructor goes through CTFE, and CTFE doesn't care all that much about the `pure` attribute. Instead, CTFE just tries to evaluate the function and aborts when it encounters an action that would be impure.
|
Copyright © 1999-2021 by the D Language Foundation