Thread overview | |||||
---|---|---|---|---|---|
|
May 09, 2016 Chaining opIndex | ||||
---|---|---|---|---|
| ||||
struct Foo { Bars bars; ... } struct Foos { Foo[] arr; Foo opIndex (size_t idx) { return arr[idx]; } ... } struct Bar { // No Car[] cars; ... } struct Bars { Bar[] arr; Bar opIndex (size_t idx) { return arr[idx]; } ... } struct Car { ... } Foos foos; Foo foo = foos[1]; // Works Bar bar = foos[1].bars[2]; // Works Car car = foos[1].bars[2].cars[3]; // Desired abstraction. For any Bar there are some Cars, but Bar doesn't hold any Cars. In other words, there could be a function Car cars (Bar bar, size_t idx) { ... }, but that would be called with parens; Car car = foos[i].bars[j].cars(k); which would be inconsistent and confusing. Defining struct Cars { Car opIndex (Bar bar, size_t idx) {} } and struct Bar { Cars cars; ... } doesn't enable chaining and then would have to be used like this, AFAIK: Car car = cars[foos[i].bars[j], k]; Which is out of the question. Any suggestions to achieve the desired abstraction in a clean manner? |
May 09, 2016 Re: Chaining opIndex | ||||
---|---|---|---|---|
| ||||
Posted in reply to deed | On Monday, 9 May 2016 at 20:14:25 UTC, deed wrote:
> struct Foo {
> Bars bars;
> ...
> }
>
> struct Foos {
> Foo[] arr;
> Foo opIndex (size_t idx) { return arr[idx]; }
> ...
> }
>
> struct Bar {
> // No Car[] cars;
> ...
> }
>
> struct Bars {
> Bar[] arr;
> Bar opIndex (size_t idx) { return arr[idx]; }
> ...
> }
>
> struct Car {
> ...
> }
>
> Foos foos;
> Foo foo = foos[1]; // Works
> Bar bar = foos[1].bars[2]; // Works
> Car car = foos[1].bars[2].cars[3]; // Desired abstraction.
>
> For any Bar there are some Cars, but Bar doesn't hold any Cars. In other words, there could be a function Car cars (Bar bar, size_t idx) { ... }, but that would be called with parens;
>
> Car car = foos[i].bars[j].cars(k);
>
> which would be inconsistent and confusing. Defining
>
> struct Cars {
> Car opIndex (Bar bar, size_t idx) {}
> }
>
> and
>
> struct Bar {
> Cars cars;
> ...
> }
>
> doesn't enable chaining and then would have to be used like this, AFAIK:
>
> Car car = cars[foos[i].bars[j], k];
>
> Which is out of the question. Any suggestions to achieve the desired abstraction in a clean manner?
There are lots of ways to approach this. Here's one possibility:
auto cars(Bar bar)
{
static struct Res
{
Bar bar;
Car opIndex(size_t i)
{
return /* e.g. getCar(bar, i); */
}
}
return Res(bar);
}
|
May 10, 2016 Re: Chaining opIndex | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Monday, 9 May 2016 at 22:33:37 UTC, John Colvin wrote:
> There are lots of ways to approach this. Here's one possibility:
>
> auto cars(Bar bar)
> {
> static struct Res
> {
> Bar bar;
> Car opIndex(size_t i)
> {
> return /* e.g. getCar(bar, i); */
> }
> }
> return Res(bar);
> }
Thanks. Didn't think of function returning struct with opIndex. Having this as opCall in a struct Cars might be a solution.
What other approaches did you have in mind?
|
Copyright © 1999-2021 by the D Language Foundation