2007-10-08
D1.0代码模拟 __traits(hasMember, ...)
通过1.0的代码完全模拟了 D 2.0 __traits(hasMember...) 和部分 getMember 的功能:
参考: http://www.digitalmars.com/d/traits.html
特别要指出的是 is(typeof(Aggr.member)) 的用法及 alias 模板参数重载来自于 redsea 兄
- import std.stdio;
- template HasMember(T, string member)
- {
- const bool HasMember = is(typeof(mixin("T." ~ member)));
- }
- template HasMember(alias X, string member)
- {
- const bool HasMember = is(typeof(mixin("X." ~ member)));
- }
- //A very limited implemention
- template GetMember(alias X, string member)
- {
- //mixin("alias X." ~ member ~ "GetMember;"); // Compiler's bug?
- mixin("alias X." ~ member ~ " DummyAlias;");
- alias DummyAlias GetMember;
- }
- template BarT()
- {
- const double PI = 3.14;
- }
- void main()
- {
- class Foo
- {
- static int n = 1;
- int m;
- void bar() {
- writefln("Foo.bar()");
- }
- static void add(int x, int y) {
- writefln("Foo.add(): ", x + y);
- }
- }
- writefln(HasMember!(Foo, "bar"));
- writefln(HasMember!(Foo, "m"));
- writefln(HasMember!(Foo, "sizeof"));
- writefln(HasMember!(Foo, "foo"));
- writefln(HasMember!(Foo, "y"));
- writefln(HasMember!(int, "sizeof")); //内置属性也支持
- writefln(HasMember!(std.stdio, "writefln")); // 支持检测模块中的成员
- writefln(HasMember!(BarT!(), "PI")); // 支持模板成员
- GetMember!(Foo, "n") = 2;
- writefln("Foo.n=", Foo.n);
- GetMember!(Foo, "add")(12, 34); //调用 Foo.add()
- }
参考: http://www.digitalmars.com/d/traits.html
特别要指出的是 is(typeof(Aggr.member)) 的用法及 alias 模板参数重载来自于 redsea 兄


评论
template myt(T)
{
static if(is(T==int))
{
void func(T t)
{
}
}
else
void func1(T t)
{
}
}
void main()
{
myt!(int).func(3);
myt!(char).func1(3);
}
因为考虑
template myt(T) { static if(is(T==int)) { void func(T t) { } } else void func1(T t) { } } void main() { myt!(int).func(3); myt!(char).func1(3); }因为考虑
template myt(T) { static if(is(T==int)) { void func(T t) { } } else void func1(T t) { } } void main() { myt!(int).func(3); myt!(char).func1(3); }我试了一下,没想到这样也能重载,如此 HasMember 模板甚至可以检测模块和模板中的成员。
OMG,D确实有点恐怖。
应该是模板选择吧 (这里似乎还不是偏特化, T 和 alias T 不兼容).
D 的特殊规则比较少就好, 函数可以重载, 模板可以重载, 最小惊讶原则做得好.
template HasMember(T, char [] member)
{
const bool HasMember =
is( typeof(mixin("T." ~ member)) );
}
template HasMember(alias T, char [] member)
{
const bool HasMember =
is( typeof(mixin("T." ~ member)) );
}
我试了一下,没想到这样也能重载,如此 HasMember 模板甚至可以检测模块和模板中的成员。
OMG,D确实有点恐怖。
用 alias 模板参数的问题是无法处理内置类型的属性,比如 int.sizeof 就无法确定。
template HasMember(T, char [] member)
{
const bool HasMember =
is( typeof(mixin("T." ~ member)) );
}
template HasMember(alias T, char [] member)
{
const bool HasMember =
is( typeof(mixin("T." ~ member)) );
}
看来, 模板中处理mixin D2.0 有改进.
template HasMember(char [] T, char [] member)
{
const bool HasMember =
is( typeof(mixin(T ~"." ~ member)) );
}