problem with alias this and Tuple
Paul Backus
snarwin at gmail.com
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:
```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
More information about the Digitalmars-d-learn
mailing list