problem with alias this and Tuple

Paul Backus snarwin at
Tue Oct 12 14:01:17 UTC 2021

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:

size_t toHash() const
     return hashOf(payload);


More information about the Digitalmars-d-learn mailing list