Accessing mutable data that isn't

Spott andrew.spott at gmail.com
Mon Nov 25 09:34:30 PST 2013


On Thursday, 21 November 2013 at 07:23:09 UTC, Jonathan M Davis
wrote:
> On Wednesday, November 20, 2013 23:49:42 Spott wrote:
>> I've been screwing around with templates lately, and I'm
>> attempting to figure out why the following won't compile:
>> 
>> struct value
>> {
>>       int a;
>> 
>>       const auto
>>           opBinary(string op, T)(in T rhs) const pure {
>>               static if (op == "+")
>>                   return 
>> intermediateValue!(value.plus,this,rhs)();
>>           }
>> 
>>       ref value opAssign(T)( in T t ) {
>>           a = t.a;
>>           return this;
>>       }
>> 
>>       static
>>       int plus(T1, T2)(in T1 x, in T2 y) pure {
>>           return x.a + y.a;
>>       }
>> 
>> }
>> 
>> struct intermediateValue(alias Op, alias A, alias B)
>> {
>> 
>>       auto opBinary(string op, T)(in T rhs) const pure {
>>           static if (op == "+")
>>               return intermediateValue!(value.plus,this,rhs)();
>>       }
>> 
>>       @property auto a() const pure {
>>           return Op(A, B);
>>       }
>> 
>> }
>> 
>> void main()
>> {
>>       value a = value(2);
>>       value b = value(3);
>>       value c;
>>       c = a + b;
>> }
>> 
>> The error is:
>> d_playground.d(34): Error: pure nested function 'a' cannot 
>> access
>> mutable data 'this'
>> d_playground.d(34): Error: pure nested function 'a' cannot 
>> access
>> mutable data 'this'
>> d_playground.d(10): Error: template instance
>> d_playground.value.opBinary!("+",
>> value).opBinary.intermediateValue!(plus, this, rhs) error
>> instantiating
>> d_playground.d(44):        instantiated from here: 
>> opBinary!("+",
>> value)
>> d_playground.d(44): Error: template instance
>> d_playground.value.opBinary!("+", value) error instantiating
>> 
>> What is going on?  Why is 'a' not allowed to "access" mutable
>> data (even though it isn't modifying it)? How do I tell the
>> compiler to pass "this" in a const fashion?
>
>
> pure functions can only access their arguments and 
> global/static constants.
> a's only argument is its invisible this pointer. Op, A, and B 
> are aliases to
> stuff outside of a. I suppose that an argument could be made 
> that because
> the're template arguments to the type that a is a part of that 
> they should be
> considered to be arguments to a like the this pointer is, but 
> you are
> essentially trying to have it access data which is not one of 
> its arguments
> and that violates purity.
>
> But all in all, I find your code quite bizarre and difficult to 
> understand -
> particularly your use of aliases - so it's kind of hard for me 
> to say how
> valid it is. I'm surprised that you can get away with feeding a 
> purely runtime
> argument to a template as an alias (namely rhs). I wouldn't 
> have thought that
> that would be valid. In most cases, all template alias 
> parameters get used for
> is passing in predicates to functions (which are almost 
> invariably delegates
> or lambdas). So, clearly my understanding of how alias template 
> parameters
> work is too limited.
>
> - Jonathan M Davis

Why is rhs a purely runtime argument?  I would think it would be
known at compile time.


More information about the Digitalmars-d-learn mailing list