www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - problem with alias this and Tuple

reply Johann Lermer <johann.lermer elvin.eu> writes:
Hi all,

I have a problem with Tuples and struct templates that contain an 
alias this:
```d
import std;

struct Element(T)
{
	T payload;
	alias payload this;

	this (T p)
	{
		payload = p;
	}
}

class Item {}

void main ()
{
	auto e = Element!Item (new Item());
	auto t = tuple(e);
}
```
dmd generates a warning: **Warning: struct Element has method 
toHash, however it cannot be called with const(Element!(Item)) 
this.
Element.toHash defined here: 
/usr/local/include/d/druntime/import/object.d(83)**

The culprit seems to be the 'alias payload this'. When I remove 
that line, the code works. However, in my code, I need that 
alias. Any ideas, what's wrong or what I could do? Thanks.
Oct 12 2021
parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 12 October 2021 at 09:30:57 UTC, Johann Lermer wrote:
 Hi all,

 I have a problem with Tuples and struct templates that contain 
 an alias this:
 ```d
 import std;

 struct Element(T)
 {
 	T payload;
 	alias payload this;

 	this (T p)
 	{
 		payload = p;
 	}
 }

 class Item {}

 void main ()
 {
 	auto e = Element!Item (new Item());
 	auto t = tuple(e);
 }
 ```
 dmd generates a warning: **Warning: struct Element has method 
 toHash, however it cannot be called with const(Element!(Item)) 
 this.
 Element.toHash defined here: 
 /usr/local/include/d/druntime/import/object.d(83)**

 The culprit seems to be the 'alias payload this'. When I remove 
 that line, the code works. However, in my code, I need that 
 alias. Any ideas, what's wrong or what I could do? Thanks.
All classes in D inherit from [`Object`][1], and `Object` has a [`toHash` method][2]. So what's happening here is (1) your `Item` class is inheriting `toHash` from `Object`, and (2) your `Element` struct is "inheriting" `toHash` from `Item` via `alias this`. This is why the compiler says, "struct `Element` has method `toHash`". For historical reasons, `Object.toHash` is not a `const` method, which means it cannot be called on a `const(Object)`. So if you had a `const(Element!Item)` and you tried to call `.toHash` on it, the compiler would rewrite the call to `.payload.toHash` using `alias this`, and then it would fail to compile, because `payload` would be a `const(Item)` (a subclass of `const(Object)`). This is why the compiler says, "however, it cannot be called with `const(Element!(Item))`". The simplest fix is to define a `toHash` method for `Element` using the built-in [`hashOf`][3] function: ```d size_t toHash() const { return hashOf(payload); } ``` [1]: https://druntime.dpldocs.info/object.Object.html [2]: https://druntime.dpldocs.info/object.Object.toHash.html [3]: https://druntime.dpldocs.info/object.hashOf.2.html
Oct 12 2021
parent reply Johann Lermer <johann.lermer elvin.eu> writes:
Thanks, understood. But isn't this a deficiency in the library 
that should be fixed?
Oct 12 2021
next sibling parent Paul Backus <snarwin gmail.com> writes:
On Tuesday, 12 October 2021 at 15:55:40 UTC, Johann Lermer wrote:
 Thanks, understood. But isn't this a deficiency in the library 
 that should be fixed?
You mean the part about how `Object.toHash` doesn't work with `const`? Yes, it is a deficiency in the library. The problem is, it cannot be fixed without breaking backwards compatibility.
Oct 12 2021
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Tuesday, 12 October 2021 at 15:55:40 UTC, Johann Lermer wrote:
 Thanks, understood. But isn't this a deficiency in the library 
 that should be fixed?
The problem extends to more than just `toHash`. Take a look at this DConf 2019 presentation by Eduard Staniloiu on ProtoObject (as proposed by Andrei Alexandrescu): https://youtu.be/EcG5mnOzZ0s Eduard is now mentoring a Symmetry Autumn of Code participant (Robert Aron) whose project is implementing `ProtoObject`. You can get a summary of the project from Robert's first weekly update thread here: https://forum.dlang.org/post/wezzcgwbnaguawzfhtpw forum.dlang.org
Oct 12 2021