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