How to make a generic function to take a class or struct by reference?

vit vit at vit.vit
Mon Mar 28 05:32:41 UTC 2022


On Sunday, 27 March 2022 at 16:27:44 UTC, JN wrote:
> I would like to have only one definition of getX if possible, 
> because they both are doing the same thing. I can't remove the 
> ref one, because without a ref it will pass the struct as a 
> temporary and compiler won't like that.
>
> ```d
> import std.stdio;
>
> struct Foo
> {
>     int x;
>
>     void doStuff()
>     {
>         *getX(this) = 5;
>     }
> }
>
> class Bar
> {
>     int x;
>
>     void doStuff()
>     {
>         *getX(this) = 5;
>     }
> }
>
> int* getX(T)(ref T t)
> {
>     return &t.x;
> }
>
> int* getX(T)(T t)
> {
>     return &t.x;
> }
>
> void main()
> {
>     Foo foo;
>     Bar bar = new Bar();
>
>     foo.doStuff();
>     bar.doStuff();
>
>     assert(foo.x == 5);
>     assert(bar.x == 5);
> }
> ```

Try this:
```d

int* getX(T)(return auto ref T t){
	static if(is(T == class))
		return &t.x;
	else static if(is(T == struct) && __traits(isRef, t))
		return &t.x;
	else
		static assert(0, "no impl " ~ T.stringof);
}
```
or:

```d

int* getX(T)(return auto ref T t)
if(is(T == class) || (is(T == struct) && __traits(isRef, t))){
	return &t.x;
}
```


More information about the Digitalmars-d-learn mailing list