inout template parameter, or a solution to the templated container issue

monarch_dodra monarchdodra at gmail.com
Thu Jun 13 00:04:45 PDT 2013


On Wednesday, 12 June 2013 at 13:04:28 UTC, deadalnix wrote:
> On Wednesday, 12 June 2013 at 12:37:13 UTC, monarch_dodra wrote:
>> OK, but how do you handle methods that rely on T being 
>> (potentially) mutable? For example:
>>
>> //----
>> struct Foo(inout T)
>> {
>>    T a;
>>    static if (isAssignable!T) //So here, "T" is actually 
>> "inout T", correct?
>>    {
>>        void opAssign(T other)
>>        {a = other.a;}
>>    }
>> }
>> //----
>>
>
> T is not assignable. If it were, you couldn't cast implicitly 
> to Foo!const(T) . You can still return a T by reference, the 
> caller know if it is mutable or not.

I'm not sure I understand the answer. If a parameter is marked as 
inout, then you are saying it must be considered as const in the 
entire struct?

*But*, when the user handles the struct, user may "interfere" 
with his own knowledge of the object's mutability?

This seems too restrictive to be useful, no? propery setters go 
out the window for non-escaping refs, amongst others. 
Implementation wise, I also don't see many usecases for useful 
structs that can't do mutating operations on T.

I think being able to mark which functions will operate only when 
T has (or lacks) specific qualifiers (because there is the same 
problem for functions that could only exist when T is immutable)? 
The problem is that the mutable->const<-immutable hierarchy is 
flipped on its head.

Not to mention that a template could have multiple parameters. 
Something like this?

struct Foo(inout T, inout U)
{
     //Function body. T and U are not qualified. User may qualify 
as wanted.

     void foo(); //normal function. T and U are "const" in here.
     void bar() const; //normal const function. T and U are also 
"const" in here.

     void foo1() inout(T); //This function requires T to be 
mutable. It will not appear in const
     void foo2() immutable(U); //This function requires (U) to be 
immutable. It will not appear in const.
     void foo3() inout(T) inout(U); //Both T and U need to be 
mutable.
     void foo4() inout(T) immutable(U); //Mix and match.
}

Or something along these lines. I couldn't really see it working 
any other way. I mean, as presented, it feels that "Foo!T" is 
simply an alias for what you'd get with "Foo!(const T)", but you 
preserve qualification information on the outside.


More information about the Digitalmars-d mailing list