On Tuesday, 16 August 2016 at 17:39:14 UTC, Lodovico Giaretta
wrote:
On Monday, 15 August 2016 at 19:31:14 UTC, Engine Machine wrote:
Suppose I have a templated type like
struct S(T) { int x; static if (T is Y) int y; }
I would like to be able to create a reference to S(T) for any
T,
struct Q
{
S!* s; // Can hold any type of S.
}
and be able to access s.x, since it is common to all S.
Can D do anything like this? It is sort of like runtime
inheritance, but at the compile time level.
I do not want to have to cast to S!T every time just to access
x, e.g.,
struct Q
{
Object s;
}
which is too general as s can be things that are not of type
S!*.
Is this possible?
I don't know if this is exactly what you want:
=====================================
import std.traits: hasMember;
struct Q(T)
if (hasMember!(T, "x"))
{
T s;
@property auto x() { return s.x; }
}
auto makeQ(T)(auto ref T val)
{
return Q!T(val);
}
auto s = myTypeWithFieldX();
auto q = makeQ(s);
assert(q.x == s.x);
=====================================
`Q` can store any type with an `x` field and gives access to
it. The auxiliary function `makeQ` acts as a constructor for
`Q` with template parameter deduction.
The only problem is Q is still defined by T. Your makeQ then
requires the type implicitly, which I don't necessarily have.
You've simply added complexity to the problem but the issue is
still there.
I realize now that D simply cannot do what I ask directly because
It's type parameters are part of the type. It can't be told that
in some cases they are not. Any use of the parameters, as I am
using them, will result in this issue.
I'm now trying a different method which builds the based types
using partial oop and partial CT code. The CT code is only for
performance and convenience anyways.