Jump to page: 1 2 3
Thread overview
opAssign and const?
May 04, 2012
Era Scarecrow
May 04, 2012
Jonathan M Davis
May 04, 2012
Era Scarecrow
May 04, 2012
Era Scarecrow
May 04, 2012
Jonathan M Davis
May 04, 2012
Era Scarecrow
May 04, 2012
Jonathan M Davis
May 04, 2012
Era Scarecrow
May 04, 2012
Era Scarecrow
May 04, 2012
Era Scarecrow
May 04, 2012
Era Scarecrow
May 04, 2012
Era Scarecrow
May 05, 2012
Jonathan M Davis
May 05, 2012
Era Scarecrow
May 05, 2012
Jonathan M Davis
May 05, 2012
Era Scarecrow
May 05, 2012
Era Scarecrow
May 05, 2012
Jonathan M Davis
May 05, 2012
Era Scarecrow
May 05, 2012
Era Scarecrow
May 05, 2012
Jonathan M Davis
May 04, 2012
 I have the following dilemma. Hopefully I have this right.

struct X {
  ref X opAssign(X x2);
  ref X opAssign(ref X x2);
}

X fn();

void func(){
  X x, x2;

  x = x2; //uses ref
  x = fn(); //without ref
}

 According to the book, this is how it is suppose to be. const is a added promise not to modify anything. So... if i changed the ref to ref const... it won't call unless the item input was const as well.

//same as above except..
struct X {
  ref X opAssign(X x2);
  ref X opAssign(ref const X x2); //const added
}

void func(){
  X x, x2;
  const X x3;

  x = x2; //without ref???
  x = x3; //ref
}

 Since the input is intended to be read only anyways, why won't it work as expected with x = x2? This seems like a bug. If it's not, then I need to make two ref versions so it will behave properly. (If you need I can past actual working example)
May 04, 2012
On Friday, May 04, 2012 07:49:29 Era Scarecrow wrote:
>   I have the following dilemma. Hopefully I have this right.
> 
> struct X {
>    ref X opAssign(X x2);
>    ref X opAssign(ref X x2);
> }
> 
> X fn();
> 
> void func(){
>    X x, x2;
> 
>    x = x2; //uses ref
>    x = fn(); //without ref
> }
> 
>   According to the book, this is how it is suppose to be. const is
> a added promise not to modify anything. So... if i changed the
> ref to ref const... it won't call unless the item input was const
> as well.
> 
> //same as above except..
> struct X {
>    ref X opAssign(X x2);
>    ref X opAssign(ref const X x2); //const added
> }
> 
> void func(){
>    X x, x2;
>    const X x3;
> 
>    x = x2; //without ref???
>    x = x3; //ref
> }
> 
>   Since the input is intended to be read only anyways, why won't
> it work as expected with x = x2? This seems like a bug. If it's
> not, then I need to make two ref versions so it will behave
> properly. (If you need I can past actual working example)

I believe that the issue is that x2 isn't const, so when the compiler decides which of the two overloads to use, it picks the one which doesn't use const. If the const ref version were the only one, then it would work with x2, but since it isn't, the other one gets picked because it's deemed a better match.

- Jonathan M Davis
May 04, 2012
On Friday, 4 May 2012 at 06:15:21 UTC, Jonathan M Davis wrote:
> I believe that the issue is that x2 isn't const, so when the compiler decides which of the two overloads to use, it picks the one which doesn't use const. If the const ref version were the only one, then it would work with x2, but since it isn't, the other one gets picked because it's deemed a better match.

 I figured that was the case too. But I get the feeling that's wrong in this case. I was hoping to have only two declared opAssing's, one for temporaries (without ref) and one for copying. Kinda like the difference between saying a=b and a[]=b[] for an array. Be annoying if I had to force the cast to be const to do what I wanted; Right?
May 04, 2012
On Friday, 4 May 2012 at 06:32:41 UTC, Era Scarecrow wrote:
> opAssing's

 Hmmm suppose to be OpAssign. Nothing quite like a bug in your automatic text converter right?

May 04, 2012
On Friday, May 04, 2012 08:32:40 Era Scarecrow wrote:
> On Friday, 4 May 2012 at 06:15:21 UTC, Jonathan M Davis wrote:
> > I believe that the issue is that x2 isn't const, so when the compiler decides which of the two overloads to use, it picks the one which doesn't use const. If the const ref version were the only one, then it would work with x2, but since it isn't, the other one gets picked because it's deemed a better match.
> 
>   I figured that was the case too. But I get the feeling that's
> wrong in this case. I was hoping to have only two declared
> opAssing's, one for temporaries (without ref) and one for
> copying. Kinda like the difference between saying a=b and a[]=b[]
> for an array. Be annoying if I had to force the cast to be const
> to do what I wanted; Right?

If you make the one which isn't a ref const as well, it'll probably work.

- Jonathan M Davis
May 04, 2012
On Friday, 4 May 2012 at 06:48:40 UTC, Jonathan M Davis wrote:
> If you make the one which isn't a ref const as well, it'll probably work.

 Yeah I think so too. It will just be either a direct copy or I cast the object as const and pass it through. Seems like extra work to me and should be handled by the compiler. Anyways, thanks for looking at the problem with me.
May 04, 2012
On Friday, May 04, 2012 08:52:49 Era Scarecrow wrote:
> On Friday, 4 May 2012 at 06:48:40 UTC, Jonathan M Davis wrote:
> > If you make the one which isn't a ref const as well, it'll probably work.
> 
>   Yeah I think so too. It will just be either a direct copy or I
> cast the object as const and pass it through. Seems like extra
> work to me and should be handled by the compiler. Anyways, thanks
> for looking at the problem with me.

With the last beta, there was a discussion in changing how ref and const ref works to allow rvalues while disallowing whatever use cases it is that causes problems with that in C++. If that gets sorted out and fully implemented, then you'd only need one overload. As it stands, the closest that you could get would be to use auto ref, but that only works with templated functions.

- Jonathan M Davis
May 04, 2012
On Friday, 4 May 2012 at 06:55:47 UTC, Jonathan M Davis wrote:
> With the last beta, there was a discussion in changing how ref and const ref works to allow rvalues while disallowing whatever use cases it is that causes problems with that in C++. If that gets sorted out and fully implemented, then you'd only need one overload. As it stands, the closest that you could get would be to use auto ref, but that only works with templated functions.

 I'll be looking forward to how that works out. I'm trying to be contentious of what code I can label as const (usable) and what I can't. I know there will be cases where I am using my struct as const, and having this minor oddity come out of the woodwork is one of the first real issues I've found that wasn't my own fault.
May 04, 2012
On Fri, 04 May 2012 02:52:49 -0400, Era Scarecrow <rtcvb32@yahoo.com> wrote:

> On Friday, 4 May 2012 at 06:48:40 UTC, Jonathan M Davis wrote:
>> If you make the one which isn't a ref const as well, it'll probably work.
>
>   Yeah I think so too. It will just be either a direct copy or I cast the object as const and pass it through. Seems like extra work to me and should be handled by the compiler. Anyways, thanks for looking at the problem with me.

I don't think it will make a copy of a temporary even if it's cast to const.  I think marking the non-ref version as const will solve the problem how you wish (as long as the argument really *isn't* modified inside that function).

-Steve
May 04, 2012
On Friday, 4 May 2012 at 12:42:54 UTC, Steven Schveighoffer wrote:
> I don't think it will make a copy of a temporary even if it's  cast to const.  I think marking the non-ref version as const  will solve the problem how you wish (as long as the argument  really *isn't* modified inside that function).

 Well the result seems to be true enough.. It also seems to work if both are const. Why didn't I consider that before? Maybe it should be noted in the next TDPL book.

import std.stdio;
import std.conv;

struct X {
  int x;
  int y;

  this (int x1, int y1) {
    x = x1; y = y1;
  }

  ref X opAssign(const X x2) {
    writeln("from temporary?");
    x=x2.x;
    y=x2.y;
    return this;
  }

  ref X opAssign(const ref X x2) {
    writeln("copy specific values?");
    x=x2.x;
    return this;
  }
}

//from temporary
X fn() {
  return X(1,2);
}

void main()
{
  X x = X(3,4);
  X y = X(5,6);

  x = y;    // 5,4 or 5,6?
  writeln("Should selectively copy (5,4) - ", to!string(x));

  x = fn();  // 1,2
  writeln("should overwrite all (1,2)- ", to!string(x));
}
« First   ‹ Prev
1 2 3