hasDataMember and mixin inconsistency
Olivier Grant
olivier.grant at gmail.com
Sat Jan 26 15:51:56 PST 2013
Hi,
First of all, I am very new to D as I've just been playing around
with it for the last week, so I might be missing something very
obvious.
I'm trying to write a template that would allow me to determine
if a struct or class has a data member with a specific name
(similar to what the hasMember template does, but only for data
members).
I originally wrote the following template :
[code]
template hasDataMember( T, string M )
{
enum hasDataMember = __traits(
compiles,
mixin("( ref T x, ref T y ){ x." ~ M ~ " = y." ~ M ~ "; }")
);
}
unittest
{
struct Test
{
struct A { }
void B( ) { }
@property A C( ) const { return F; }
@property long D( ) const { return E; }
@property void D( long e ) { E = e; }
long E;
A F;
}
assert(!hasDataMember!(int,"A"));
assert(!hasDataMember!(int,"init"));
//assert(!hasDataMember!(Test,"init")); // This fails, why?
assert(!hasDataMember!(Test,"A"));
assert(!hasDataMember!(Test,"B"));
assert(!hasDataMember!(Test,"C"));
assert( hasDataMember!(Test,"D"));
assert( hasDataMember!(Test,"E"));
assert( hasDataMember!(Test,"F"));
}
[/code]
And it works pretty well, but it gets the wrong result for the
following test case which is commented out. Originally, I thought
maybe you were allowed to write to the .init member of
structures, but writing the same code directly without relying on
a mixin actually yields the right result (all the asserts pass):
[code]
struct A { int b_; }
assert(!__traits(compiles,( ref int x, ref int y ){ x.init =
y.init; }));
assert(!__traits(compiles,( ref Test0 x, ref Test0 y ){ x.init =
y.init; }));
assert( __traits(compiles,( ref Test0 x, ref Test0 y ){ x.b_ =
y.b_; }));
[/code]
So I have two questions :
1) Why is there this inconsistency between the mixin and direct
version ?
2) Is there a better way to check for the existence of a data
member ?
Best regards,
Olivier.
More information about the Digitalmars-d-learn
mailing list