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 兄
评论
oldrev
2007-10-22
刚才发现了一个大问题,似乎2.0的 __traits 无法处理函数重载。比如 __traits(allMember) 只能返回所有方法的签名,同名的重载函数无法去分开,getMember 也有同样的问题。
DavidL
2007-10-12
嗯, javaeye的code在回复里面有bug啊
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);
}
DavidL
2007-10-12
不可能支持未实例化的模板的
因为考虑
因为考虑
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);
}
DavidL
2007-10-12
不可能支持未实例化的模板的
因为考虑
因为考虑
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);
}
oldrev
2007-10-11
在两个模板里分别加入 pragma(msg) 就知道编译器优先选择了 alias 模板。在上面的测试程序中,只有 HasMember!(int,... 那行选择了非 alias 模板。似乎是 alias 参数化符号的优先级比较高,但是文档里没有明确。
redsea
2007-10-11
引用
我试了一下,没想到这样也能重载,如此 HasMember 模板甚至可以检测模块和模板中的成员。
OMG,D确实有点恐怖。
应该是模板选择吧 (这里似乎还不是偏特化, T 和 alias T 不兼容).
D 的特殊规则比较少就好, 函数可以重载, 模板可以重载, 最小惊讶原则做得好.
oldrev
2007-10-11
引用
这样用, 就不必使用麻烦的字符串, 而且可以解决我上面说的问题了:
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)) );
}
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确实有点恐怖。
oldrev
2007-10-11
我的程序就是在 1.0 下测试通过的,GDC 0.24 && DMD 1.20
用 alias 模板参数的问题是无法处理内置类型的属性,比如 int.sizeof 就无法确定。
用 alias 模板参数的问题是无法处理内置类型的属性,比如 int.sizeof 就无法确定。
redsea
2007-10-11
这样用, 就不必使用麻烦的字符串, 而且可以解决我上面说的问题了:
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)) );
}
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)) );
}
redsea
2007-10-11
我碰到的问题是, 我要进行判断的不是一个类, 而是alias 参数, 用做 mixin part, 用第一种形式的话, 无论我是将 alias 参数实例化作为参数, 还是 mixin part 名字作为参数均错, 只能用我提供的第二种形式.
redsea
2007-10-11
我搞错了, 直接用参数 T 而不是字符串, 是可以的, 我之前可能碰到其他问题了.
redsea
2007-10-11
哦, 对了, 我用的是 1.018, 是不是太老了 
redsea
2007-10-11
D1.0 下面要写成这样才能用.
看来, 模板中处理mixin D2.0 有改进.
template HasMember(char [] 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)) );
}
tomqyp
2007-10-08
怎么不能收藏呢
发表评论
- 浏览: 93647 次
- 性别:

- 来自: 昆明

- 详细资料
搜索本博客
我的相册
Screenshot
共 1 张
共 1 张
最近加入圈子
最新评论
-
Range Coding 的 D 实现 ...
引用oldrev 2008-01-12LZMA SDK 只是一个 LZMA 算法 ...
-- by oldrev -
D 静态数组初始化大bug ...
看看日期好伐?
-- by oldrev -
D新闻组里的天才代码
没看过产生的汇编代码,测试了是可行的。如果用宏来实现就完美了
-- by oldrev -
D新闻组里的天才代码
这里的lazy根本没推后evaluate吧? 这个的优化我看在于用了一条指令来决 ...
-- by DavidL -
D 静态数组初始化大bug ...
dmd 1.028编译成功!
-- by honglang13






评论排行榜