On Wed, Aug 02, 2017 at 01:15:44PM -0400, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
[...]
> It's not currently legal, you can't have inout members of a struct.
> This could be added, but it still wouldn't work, because you can't
> "strip off" the inout part upon return.
> 
> The real answer is to have tail modifiers for structs, so you can do
> the same thing an array does. Note that if Result is an array, you CAN
> use inout:
> 
> auto byPair(AA)(inout(AA) aa)
> {
>    alias Result = inout(X)[];
>    return Result(...);
> }
[...]

Yeah, this isn't the first time I've run into this.  But then the
problem becomes, how do you design tail modifiers for structs?  Because
here the inout (or its equivalent) has to apply to one specific member;
the range methods can't also inherit the modifier otherwise in the const
case you wouldn't be able to implement popFront().

I suppose, within the current type system, you'd have to template on
modifiers, as you said, so that the incoming modifier is properly
represented in the resulting type.  But since we're already templating
on the AA type, perhaps what we could do is something like:

        auto byPair(AA)(inout(AA) aa)
        {
                alias Modifiers = std.traits.getModifiers!AA;
                struct Result {
                        std.traits.ApplyModifiers!(Slot*, Modifiers) slot;
                        ... // range methods here
                }
                return Result(aa);
        }

Of course, getModifiers and ApplyModifiers are fictitious Phobos
templates, but you get the idea.


T

-- 
Дерево держится корнями, а человек - друзьями.

Reply via email to