Typeof woes

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Aug 20 17:09:52 PDT 2013


On Wed, Aug 21, 2013 at 01:42:11AM +0200, Marek Janukowicz wrote:
> Given this short program:
> 
> class A {
> 
>   int i;
>   //enum Smth { X };
> 
>   void list () {
>     foreach( s; __traits(derivedMembers, typeof(this))) {
>       alias type = typeof(__traits(getMember, this, s));
>     }
>   }
> }
> 
> void main () {
>   A a = new A();
>   a.list();
> }
> 
> if I uncomment "enum" line I get compilation error:
> aa.d(8): Error: argument Smth to typeof is not an expression
> 
> So far it only happened with enums for me, but admittedly I didn't
> check all the possible types out there.

The reason is that derivedMembers returns *all* members, including enum
definitions, not just member variables and methods. So this includes
'Smth', and typeof(this.Smth) is invalid because this.Smth is already a
type, so you can't apply typeof to it.

To get around this, you will need to use static if, maybe something like
this:

	void list() {
		// Warning: untested code
		foreach(s; __traits(derivedMembers, typeof(this))) {
			static if (is(typeof(__traits(getMember, this, s)) type)) {
				// here, 'type' is bound to the type of
				// the member.
			}
		}
	}

This uses the is(X Y) form, where if X is a valid type, then it gets
aliased to Y inside the static if block. (I have to admit I'm not that
pleased with D's is-expressions due to their confusing syntax, but they
do work and are quite a powerful tool to use once you understand them.)


> What's even more interesting it's just alias problem, the expression
> "typeof(__traits(getMember, this, s))" might be used eg. in static if
> even for enums.
> 
> Is this a bug or do I miss something (again)?
[...]

Are you sure about that? That doesn't sound right to me.


T

-- 
Lottery: tax on the stupid. -- Slashdotter


More information about the Digitalmars-d-learn mailing list