Thread overview | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 24, 2006 C++ reference type | ||||
---|---|---|---|---|
| ||||
Will C++ reference type ever be included in D? In one form or the other? |
June 24, 2006 Re: C++ reference type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tesuji | Tesuji napsal(a):
> Will C++ reference type ever be included in D? In one form or the other?
>
>
what do you mean? every complex object is internally passed by reference, and if you want the same behaviour as in c++ references, try inout keyword in declaration:
D: void func(inout int a);
is equal to
C++: void func(int &a);
|
June 24, 2006 Re: C++ reference type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yossarian | Yossarian wrote:
> Tesuji napsal(a):
>
>> Will C++ reference type ever be included in D? In one form or the other?
>>
>>
> what do you mean? every complex object is internally passed by reference, and if you want the same behaviour as in c++ references, try inout keyword in declaration:
> D: void func(inout int a);
> is equal to
> C++: void func(int &a);
The only thing missing is a reference return type.
|
June 24, 2006 Re: C++ reference type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hasan Aljudy | Hasan Aljudy wrote:
> Yossarian wrote:
>
>> Tesuji napsal(a):
>>
>>> Will C++ reference type ever be included in D? In one form or the other?
>>>
>>>
>> what do you mean? every complex object is internally passed by reference, and if you want the same behaviour as in c++ references, try inout keyword in declaration:
>> D: void func(inout int a);
>> is equal to
>> C++: void func(int &a);
>
>
> The only thing missing is a reference return type.
The attribute functions in classes serve this purpose do they not?
C++:
int& my_attr();
D:
void my_attr( int );
-DavidM
use, in both cases:
foo.my_attr = 100;
-DavidM
|
June 24, 2006 Re: C++ reference type | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Medlock | David Medlock wrote: > The attribute functions in classes serve this purpose do they not? > > C++: > int& my_attr(); > > D: > void my_attr( int ); > > use, in both cases: > foo.my_attr = 100; Unless you want to be able to say 'foo.my_attr++;' or 'foo.someStruct.bar = 1;' The latter can be accomplished by making the function return a pointer to the struct, but then you cant say 'Foo x = my_attr();' -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/ |
June 24, 2006 Re: C++ reference type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | Tom S wrote:
> David Medlock wrote:
>
>> The attribute functions in classes serve this purpose do they not?
>>
>> C++:
>> int& my_attr();
>>
>> D:
>> void my_attr( int );
>>
>> use, in both cases:
>> foo.my_attr = 100;
>
>
> Unless you want to be able to say 'foo.my_attr++;'
> or 'foo.someStruct.bar = 1;'
>
> The latter can be accomplished by making the function return a pointer to the struct, but then you cant say 'Foo x = my_attr();'
>
>
Ok, but what exactly does that buy you?
If you want reference semantics use a class.
If you want opPostInc use a struct.
Even without you could just as easily say:
int bar(int r) { return this.someStruct.bar = r; }
if you have several 'bars' perhaps its time to refactor?
Its like saying : I cant ride my car on bike trails, even though I can ride my bike on roads. Just use the bike.
-DavidM
|
June 24, 2006 Re: C++ reference type | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Medlock | David Medlock wrote: > Tom S wrote: >> David Medlock wrote: >> >>> The attribute functions in classes serve this purpose do they not? >>> >>> C++: >>> int& my_attr(); >>> >>> D: >>> void my_attr( int ); >>> >>> use, in both cases: >>> foo.my_attr = 100; >> >> >> Unless you want to be able to say 'foo.my_attr++;' >> or 'foo.someStruct.bar = 1;' >> >> The latter can be accomplished by making the function return a pointer to the struct, but then you cant say 'Foo x = my_attr();' >> >> > Ok, but what exactly does that buy you? > > If you want reference semantics use a class. > If you want opPostInc use a struct. > > Even without you could just as easily say: > > int bar(int r) { return this.someStruct.bar = r; } > > if you have several 'bars' perhaps its time to refactor? > > Its like saying : I cant ride my car on bike trails, even though I can ride my bike on roads. Just use the bike. Excuse me, but I have no idea what you're talking about. Reference return types are useful in many cases. E.g. if you want to implement your own Array class. With normal arrays you can say: int[] arr1; ... ; arr1[0] += 2; but when you define your own array, like: Array!(int) arr2; ... ; then how do you implement 'arr2[0] += 2;' ? You can't, because there are only opIndex and opIndexAssign operators. There's no opIndexAddAssign and opIndex*Assign for that purpose :0 This gets worse, e.g. if you have a struct Foo { int bar; } Foo[] arr3; ... ; arr3[0].bar = 1; but when you define Array!(Foo) arr4; ... ; then to accomplish the 'arr4[0].bar = 1;' functionality, you have to make opIndex return a pointer. Yet then you can't say 'Foo x = arr4[0];' because there's a type mismatch. You'd have to dereference the pointer. -- Tomasz Stachowiak /+ a.k.a. h3r3tic +/ |
June 24, 2006 Re: C++ reference type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Hasan Aljudy | Hasan Aljudy wrote: > Yossarian wrote: >> Tesuji napsal(a): >> >>> Will C++ reference type ever be included in D? In one form or the other? >>> >>> >> what do you mean? every complex object is internally passed by reference, and if you want the same behaviour as in c++ references, try inout keyword in declaration: >> D: void func(inout int a); >> is equal to >> C++: void func(int &a); > > The only thing missing is a reference return type. There's one more irritating limitation, and that is the ability to pass a temporary byref: private import std.stdio; void main() { // error: (opCall)(100) is not an lvalue writefln(foo(MyStruct(100),100)); } int foo(inout MyStruct s, int i) { return s.i * i; } struct MyStruct { private int i = 0; static MyStruct opCall(int i) { MyStruct s; s.i = i; return s; } } I think the 'byref' modifier could be added to allow this. In the compiler it could be implemented the same as 'inout' except that the lvalue limitation would not be enforced. In C++ you'd have to do 'const <type> &', but I'm not suggesting we get into the const debate again just for this purpose; just add the byref for cases like that, for cases where the programmer just wants to pass byref w/o an intention to modify the parameter, and also the 'byref' modifier could then be used for function return types as well (makes more sense to me than using 'inout' for return types). - Dave |
June 24, 2006 Re: C++ reference type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | Tom S wrote: > David Medlock wrote: > > Tom S wrote: > > > David Medlock wrote: > > > > > > > The attribute functions in classes serve this purpose do they not? > > > > > > > > C++: > > > > int& my_attr(); > > > > > > > > D: > > > > void my_attr( int ); > > > > > > > > use, in both cases: > > > > foo.my_attr = 100; > > > > > > > > > Unless you want to be able to say 'foo.my_attr++;' > > > or 'foo.someStruct.bar = 1;' > > > > > > The latter can be accomplished by making the function return a pointer to the struct, but then you cant say 'Foo x = my_attr();' > > > > > > > > Ok, but what exactly does that buy you? > > > > If you want reference semantics use a class. > > If you want opPostInc use a struct. > > > > Even without you could just as easily say: > > > > int bar(int r) { return this.someStruct.bar = r; } > > > > if you have several 'bars' perhaps its time to refactor? > > > > Its like saying : I cant ride my car on bike trails, even though I can ride my bike on roads. Just use the bike. > > Excuse me, but I have no idea what you're talking about. Reference return types are useful in many cases. E.g. if you want to implement your own Array class. With normal arrays you can say: > > int[] arr1; ... ; arr1[0] += 2; > > but when you define your own array, like: > > Array!(int) arr2; ... ; > > then how do you implement 'arr2[0] += 2;' ? > > You can't, because there are only opIndex and opIndexAssign operators. There's no opIndexAddAssign and opIndex*Assign for that purpose :0 > > This gets worse, e.g. if you have a > > struct Foo { > int bar; > } > > Foo[] arr3; ... ; arr3[0].bar = 1; > > but when you define > > Array!(Foo) arr4; ... ; > > then to accomplish the 'arr4[0].bar = 1;' functionality, you have to make opIndex return a pointer. Yet then you can't say 'Foo x = arr4[0];' because there's a type mismatch. You'd have to dereference the pointer. Yeah, I agree, D constraints in these cases are really irritating. -- AKhropov |
June 25, 2006 Re: C++ reference type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tom S | Tom S wrote: > David Medlock wrote: > >> Tom S wrote: >> >>> David Medlock wrote: >>> >>>> The attribute functions in classes serve this purpose do they not? >>>> >>>> C++: >>>> int& my_attr(); >>>> >>>> D: >>>> void my_attr( int ); >>>> >>>> use, in both cases: >>>> foo.my_attr = 100; >>> >>> >>> >>> Unless you want to be able to say 'foo.my_attr++;' >>> or 'foo.someStruct.bar = 1;' >>> >>> The latter can be accomplished by making the function return a pointer to the struct, but then you cant say 'Foo x = my_attr();' >>> >>> >> Ok, but what exactly does that buy you? >> >> If you want reference semantics use a class. >> If you want opPostInc use a struct. >> This should have read 'value semantics' not opPostInc. <snip> > Excuse me, but I have no idea what you're talking about. I am talking about 'possible' versus 'thats how we do it in C++'. If you want to use C++ idioms, then yes its very hard to use D that way. The point was that its (somewhat of) a shortcoming. Certain C++ idioms require new ones in D. Thats not 'worse', its just different. > Reference return types are useful in many cases. > E.g. if you want to implement > your own Array class. With normal arrays you can say: > > int[] arr1; ... ; arr1[0] += 2; > > but when you define your own array, like: > > Array!(int) arr2; ... ; > > then how do you implement 'arr2[0] += 2;' ? > > You can't, because there are only opIndex and opIndexAssign operators. There's no opIndexAddAssign and opIndex*Assign for that purpose :0 You can't opAddAssign in that case yes, but you can add 2 to the first item with: arr2[0] = arr2[0] + 2; Is this really a lot worse? Its maybe 2-3 cycles at the most? > This gets worse, e.g. if you have a > > struct Foo { > int bar; > } > > Foo[] arr3; ... ; arr3[0].bar = 1; > > but when you define > > Array!(Foo) arr4; ... ; > > then to accomplish the 'arr4[0].bar = 1;' functionality, you have to make opIndex return a pointer. Yet then you can't say 'Foo x = arr4[0];' because there's a type mismatch. You'd have to dereference the pointer. Not to pick but you could say: auto x = arr4[0]; x.bar = 100; or you could simply use a different method: class Array(T) { T[] items; ... T* ptr(int n=0) { return items.ptr + n ; } } arr.ptr[5].bar = 1; Since the built int arrays use a .ptr property, I usually define this method anyways. Once you use it for a while its second nature. If you need to change a lot of entries, use foreach which returns an inout reference. If you want to get crazy: void opIndexAssign( void delegate(T* item) fn, int n ) { fn( items.ptr + n ); } then: arr[0] = (Foo* f){f.bar += 3;}; hehe :P Seriously though, if the item is small enough to not warrant a class, then just extend the container class and define a custom method to update the item. -DavidM |
Copyright © 1999-2021 by the D Language Foundation