Thread overview
Pass enum variable as const ref arg
Dec 04, 2020
Andrey
Dec 04, 2020
rikki cattermole
Dec 04, 2020
Andrey
Dec 04, 2020
rikki cattermole
Dec 04, 2020
Paul Backus
Dec 04, 2020
Andrey
Dec 04, 2020
Bastiaan Veelo
Dec 08, 2020
Q. Schroll
December 04, 2020
Hello,

> void test(const ref string[3] qazzz) { qazzz.writeln; }
> 
> void main()
> {
>     enum string[3] value = ["qwer", "ggg", "v"];
>     test(value);
> }

Gives errors:

> onlineapp.d(26): Error: function onlineapp.test(ref const(string[3]) qazzz) is not callable using argument types (string[3])
> onlineapp.d(26):        cannot pass rvalue argument ["qwer", "ggg", "v"] of type string[3] to parameter ref const(string[3]) qazzz

WTF?
December 05, 2020
On 05/12/2020 1:54 AM, Andrey wrote:
> Hello,
> 
>> void test(const ref string[3] qazzz) { qazzz.writeln; }
>>
>> void main()
>> {
>>     enum string[3] value = ["qwer", "ggg", "v"];

That is a compile time constant (remove the enum).

>>     test(value);
>> }
> 
> Gives errors:
> 
>> onlineapp.d(26): Error: function onlineapp.test(ref const(string[3]) qazzz) is not callable using argument types (string[3])
>> onlineapp.d(26):        cannot pass rvalue argument ["qwer", "ggg", "v"] of type string[3] to parameter ref const(string[3]) qazzz
> 
> WTF?

The ref. The problem is the ref. You are passing it a constant, not a variable.
December 04, 2020
Hm, you mean that enum variable is not a real variable?
I thought that to make CT variable you should mark it as enum (in c++ as constexpr).
How to do it here?
December 05, 2020
On 05/12/2020 2:42 AM, Andrey wrote:
> Hm, you mean that enum variable is not a real variable?

It is not a variable. It is a constant that cannot be changed and does not exist in the executable.

> I thought that to make CT variable you should mark it as enum (in c++ as constexpr).
> How to do it here?

You are already doing it. This is not what you want. You want a variable that will pass by ref. Remove enum.
December 04, 2020
On Friday, 4 December 2020 at 13:42:45 UTC, Andrey wrote:
> Hm, you mean that enum variable is not a real variable?
> I thought that to make CT variable you should mark it as enum (in c++ as constexpr).
> How to do it here?

The official name for what you're calling an "enum variable" is "manifest constant" [1]. Manifest constants are like named literals: when you use one, it is treated by the compiler as though you had copy-and-pasted its value at that point in the code. So, for example,

    enum string[3] value = ["qwer", "ggg", "v"];
    test(value);

...is equivalent to

    test(cast(string[3]) ["qwer", "ggg", "v"]);

If you want to declare a compile-time constant that's also an lvalue, you can use `static immutable` instead of `enum`:

    static immutable string[3] value = ["qwer", "ggg", "v"];
    test(value);

[1] https://dlang.org/spec/enum.html#manifest_constants
December 04, 2020
Thank you!
December 04, 2020
On Friday, 4 December 2020 at 12:54:25 UTC, Andrey wrote:
> Hello,
>
>> void test(const ref string[3] qazzz) { qazzz.writeln; }
>> 
>> void main()
>> {
>>     enum string[3] value = ["qwer", "ggg", "v"];
>>     test(value);
>> }
>
> Gives errors:

It works if you pass `-preview=rvaluerefparam` to the compiler.

But the other suggestions are better IMO.

—Bastiaan.
December 08, 2020
On Friday, 4 December 2020 at 12:54:25 UTC, Andrey wrote:
> [...]
> WTF?

If you come from a C or C++ background, it's quite reasonable to think of enum stuff like a #define macro. You're using static arrays, but note that array literals allocate in many use cases. It really is like a C/C++ macro. Use n times = allocate n times. You avoid that with a static immutable completely. That said, if you use the value of that enum only at compile-time, there's no need for a static immutable.

Hope that this rule of thumb sheds some more light on how to achieve certain stuff.