www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Error: non-constant expression

reply "Dfr" <deflexor yandex.ru> writes:
Hello, this example:

import std.array;
import std.algorithm;
import std.typecons;

auto a = [["test", "1"]];
auto b = a.map!(x=>tuple(x[1],x[0])).assocArray;

Gives me
Error: static variable a cannot be read at compile time

When add "const":

const auto a = [["test", "1"]];
const auto b = a.map!(x=>tuple(x[1],x[0])).assocArray;

Gives another error:
Error: non-constant expression ["1":"test"]

Any idea what is wrong ?
Dec 25 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 12/25/2013 10:33 PM, Dfr wrote:

 Hello, this example:

 import std.array;
 import std.algorithm;
 import std.typecons;

 auto a = [["test", "1"]];
 auto b = a.map!(x=>tuple(x[1],x[0])).assocArray;

 Gives me
 Error: static variable a cannot be read at compile time
Are those at module scope (i.e. outside of any function)? Although it can be argued that it should be possible to produce the initial value of b at compile time, it is currently not possible. Workarounds: a) If you did not want to define a and b at compile time anyway, define them at e.g. inside a function. It looks like for this example only b needs to be initialized at run time: import std.array; import std.algorithm; import std.typecons; auto a = [["test", "1"]]; void main() { auto b = a.map!(x=>tuple(x[1],x[0])).assocArray; } b) If they should really be at module scope, then initialize them inside 'static this()'. Again, only b needs to be initialized at run time: import std.array; import std.algorithm; import std.typecons; auto a = [["test", "1"], ["another", "2" ]]; // A function that produces the initial value of b: auto init_b() { return a.map!(x=>tuple(x[1],x[0])).assocArray; } // This alias is not necessary but makes the code easier to read: alias BType = typeof(init_b()); // Module-scope variable: BType b; static this() { b = init_b(); } void main() { import std.stdio; writefln("%(%s -> %s\n%)", b); }
 When add "const":

 const auto a = [["test", "1"]];
 const auto b = a.map!(x=>tuple(x[1],x[0])).assocArray;

 Gives another error:
 Error: non-constant expression ["1":"test"]

 Any idea what is wrong ?
You should be able to add 'const' to either option above. However, note that 'const auto' is redundant in D. Unlike C++, D has type inference. :p const (or immutable, or anything else) alone to infer type when possible: const a = [["test", "1"], ["another", "2" ]]; const BType b; In other words, you type 'auto' only when there is no other qualifier. Ali
Dec 26 2013
parent "Jakob Ovrum" <jakobovrum gmail.com> writes:
On Thursday, 26 December 2013 at 08:35:58 UTC, Ali Çehreli wrote:
 Are those at module scope (i.e. outside of any function)? 
 Although it can be argued that it should be possible to produce 
 the initial value of b at compile time, it is currently not 
 possible.
To elaborate: the problem is not with the computation of b's initializer (duh, it even prints the result in the error message), but attempting to retain an associative array created at compile-time for runtime. There is some progress in this area; as of last release (or maybe the one before that?), we are able to transfer class instances created at compile-time to runtime. It may take some time before we gain the same capability for associatve arrays, because their implementation is a tangled mess, but it is a work in progress.
Dec 26 2013