New operators opStaticIndex and friends

Exil Exil at gmall.com
Thu May 16 21:13:24 UTC 2019


On Thursday, 16 May 2019 at 08:28:35 UTC, Simen Kjærås wrote:
> On Wednesday, 15 May 2019 at 20:04:29 UTC, Exil wrote:
>> On Wednesday, 15 May 2019 at 09:05:20 UTC, Simen Kjærås wrote:
>>> On Wednesday, 15 May 2019 at 01:42:57 UTC, Exil wrote:
>>>> Does it need to be called opStaticIndex? Could it just be 
>>>> called opIndex and require the specific template arguments. 
>>>> If you define opIndex(int)() now, it will never be called 
>>>> right (unless you specifically invoke it)?
>>>
>>> Correct. But opIndex(T...)(Foo!T t) may be, and could then be 
>>> called as either
>>>
>>>     s[0](Foo!0.init)
>>>
>>> or
>>>
>>>     s[Foo!0.init]
>>>
>>> Not sure if this is a big issue, but it's at least indicative 
>>> of possible other issues.
>>>
>>> --
>>>   Simen
>>
>>
>>     s[0](Foo!0.init) // -> s.opIndex!(0)()(Foo!0.init)
>>     s[Foo!0.init]    // -> s.opIndex(Foo!0.init);
>>
>> If it compiled would entire depend on what opIndex returns, 
>> the arguments passed to opIndex() are the values in "[]" not 
>> the brackets, which is a separate call.
>>
>> Unless you meant this?
>>
>>     s[0, Foo!0.init];
>>
>> Which would then be difficult to know which function to call 
>> as it takes in a compile-time value and a run-time value.
>
> I meant exactly what I wrote. Since s[0] would be compile-time, 
> the arguments passed to opIndex would indeed be 0. This would 
> evaluate to a function taking a Foo!0. We could define that to 
> be immediately called with no run-time arguments, but that 
> complicates certain patterns that may be of interest:
>
> struct S {
>     template opIndex(size_t idx) {
>         static if (idx == 0) alias opIndex = fun1;
>         else alias opIndex = fun2;
>     }
>
>     void fun1(size_t i)(Foo!i value) {}
>     void fun2() {}
> }
>
> S s;
> s[0](Foo!0.init); // Should call fun1 with Foo!0.init.
> s[1](); // Should call fun2 with no args.
>
> If immediate call was implemented, the above would look like 
> this:
>
> struct S {
>     auto opIndex(size_t idx)() {
>         static if (idx == 0) return &fun1!idx;
>         else return &fun2;
>     }
>
>     void fun1(size_t i)(Foo!i value) {}
>     void fun2() {}
> }
>
> Suddenly I'm dealing with function pointers instead of aliases, 
> and this forces you to special-case functions while values, 
> types, and aliases to everything but functions follow the same 
> pattern.
>
> Of course, if no run-time arguments were given and there is no 
> & operator before s[0], calling the returned function 
> immediately might be the sane thing to do.
>
> --
>   Simen

Well now your example doesn't have opIndex(T...)() that your 
original post did. I also don't see how this is a problem 
specifically if it was named opIndex. Seems more like a detail 
that would have to be ironed out either way to ensure templates 
can be used with opStaticIndex/opIndex.


More information about the Digitalmars-d mailing list