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