`
oldrev
  • 浏览: 234400 次
  • 性别: Icon_minigender_1
  • 来自: 昆明
社区版块
存档分类
最新评论

D1.0代码模拟 __traits(hasMember, ...)

 
阅读更多
通过1.0的代码完全模拟了 D 2.0 __traits(hasMember...) 和部分 getMember 的功能:

 
  1. import std.stdio;  
  2.   
  3. template HasMember(T, string member)  
  4. {  
  5.     const bool HasMember = is(typeof(mixin("T." ~ member)));  
  6. }  
  7.   
  8. template HasMember(alias X, string member)  
  9. {  
  10.     const bool HasMember = is(typeof(mixin("X." ~ member)));  
  11. }  
  12.   
  13. //A very limited implemention  
  14. template GetMember(alias X, string member)  
  15. {  
  16.     //mixin("alias X." ~ member ~ "GetMember;"); // Compiler's bug?  
  17.     mixin("alias X." ~ member ~ " DummyAlias;");  
  18.     alias DummyAlias GetMember;  
  19. }  
  20.   
  21. template BarT()  
  22. {  
  23.     const double PI = 3.14;  
  24. }  
  25.   
  26. void main()  
  27. {  
  28.     class Foo  
  29.     {  
  30.         static int n = 1;  
  31.         int m;  
  32.         void bar() {   
  33.             writefln("Foo.bar()");  
  34.         }  
  35.         static void add(int x, int y) {  
  36.             writefln("Foo.add(): ", x + y);  
  37.         }  
  38.     }  
  39.   
  40.     writefln(HasMember!(Foo, "bar"));  
  41.     writefln(HasMember!(Foo, "m"));  
  42.     writefln(HasMember!(Foo, "sizeof"));  
  43.     writefln(HasMember!(Foo, "foo"));  
  44.     writefln(HasMember!(Foo, "y"));  
  45.     writefln(HasMember!(int"sizeof")); //内置属性也支持  
  46.     writefln(HasMember!(std.stdio, "writefln")); // 支持检测模块中的成员  
  47.     writefln(HasMember!(BarT!(), "PI")); // 支持模板成员 
  48.       
  49.     GetMember!(Foo, "n") = 2;  
  50.     writefln("Foo.n=", Foo.n);  
  51.     GetMember!(Foo, "add")(12, 34); //调用 Foo.add()  
  52. }  

参考: http://www.digitalmars.com/d/traits.html
特别要指出的是 is(typeof(Aggr.member)) 的用法及 alias 模板参数重载来自于 redsea 兄
分享到:
评论
14 楼 oldrev 2007-10-22  
刚才发现了一个大问题,似乎2.0的 __traits 无法处理函数重载。比如 __traits(allMember) 只能返回所有方法的签名,同名的重载函数无法去分开,getMember 也有同样的问题。
13 楼 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);
}

12 楼 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);
}
11 楼 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);
}
10 楼 oldrev 2007-10-11  
在两个模板里分别加入 pragma(msg) 就知道编译器优先选择了 alias 模板。在上面的测试程序中,只有 HasMember!(int,... 那行选择了非 alias 模板。似乎是 alias 参数化符号的优先级比较高,但是文档里没有明确。
9 楼 redsea 2007-10-11  
引用

我试了一下,没想到这样也能重载,如此 HasMember 模板甚至可以检测模块和模板中的成员。
OMG,D确实有点恐怖。


应该是模板选择吧 (这里似乎还不是偏特化, T 和 alias T 不兼容).

D 的特殊规则比较少就好, 函数可以重载, 模板可以重载, 最小惊讶原则做得好.
8 楼 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)) );
}

我试了一下,没想到这样也能重载,如此 HasMember 模板甚至可以检测模块和模板中的成员。
OMG,D确实有点恐怖。
7 楼 oldrev 2007-10-11  
我的程序就是在 1.0 下测试通过的,GDC 0.24 && DMD 1.20

用 alias 模板参数的问题是无法处理内置类型的属性,比如 int.sizeof 就无法确定。
6 楼 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)) );
}
5 楼 redsea 2007-10-11  
我碰到的问题是, 我要进行判断的不是一个类, 而是alias 参数, 用做 mixin part, 用第一种形式的话, 无论我是将 alias 参数实例化作为参数, 还是 mixin part 名字作为参数均错, 只能用我提供的第二种形式.
4 楼 redsea 2007-10-11  
我搞错了, 直接用参数 T 而不是字符串, 是可以的, 我之前可能碰到其他问题了.
3 楼 redsea 2007-10-11  
哦, 对了, 我用的是 1.018, 是不是太老了 
2 楼 redsea 2007-10-11  
D1.0 下面要写成这样才能用.

看来, 模板中处理mixin D2.0 有改进.
template HasMember(char [] T, char [] member)
{
    const bool HasMember =
        is( typeof(mixin(T ~"." ~ member)) );
}
1 楼 tomqyp 2007-10-08  
怎么不能收藏呢

相关推荐

    stl_algobase.h

    #include <type_traits.h> #endif #include <string.h> #include <limits.h> #include <stdlib.h> #include <stddef.h> #include <new.h> #ifdef __STL_USE_NEW_IOSTREAMS #include #else /* __STL_USE_NEW_...

    Impacts of Organizational Culture__ and Personality Traits on Decision-making in Technical Organizations.pdf

    Impacts of Organizational Culture__ and Personality Traits on Decision-making in Technical Organizations.pdf

    c++_traits.pdf

    以上代码定义了一个`is_interesting`Traits类,它可以检测特定类型是否“有趣”(在此处指`int`和`float`)。 ```cpp template, bool interesting> struct function_selector { static void function_impl...

    R Material_traits.html

    R Material_traits.html

    traits-6.1.0-cp36-cp36m-win_amd64.rar

    包含内容:traits-6.1.0-cp36-cp36m-win_amd64.whl 安装tvtk需要 VTK-7.1.1-cp36-cp36m-win_amd64.whl numpy-1.12.1+mkl-cp36-cp36m-win_amd64.whl traits-4.6.0-cp36-cp36m-win_amd64.whl mayavi-4.5.0+vtk71-cp36...

    boost_1_49_0.tar.gz

    8. **泛型编程库**:Boost.MPL和Boost.TypeTraits是泛型编程的重要工具,帮助开发者编写更高效、更具扩展性的代码。 9. **预处理库**:Boost.Preprocessor提供了一套宏系统,可以在编译时进行代码生成。 10. **...

    boost_1_58_0.zip

    Boost库,全称为C++ Boost库,是一个广受欢迎的开源C++库集合,旨在提高C++程序员的效率和代码的可移植性。Boost库由Boost社区的开发者们精心设计和维护,它不仅提供了对C++标准库的补充,还引入了许多现代编程技术...

    traits-4.6.0-cp36-cp36m-win_amd64.whl

    Python科学计算三维可视化应用中需要安装TVTK库,traits-4.6.0-cp36-cp36m-win_amd64.whl为安装TVTK库所需要的5个库之一,该库为64位的

    PHP 实现代码复用的一个方法 traits新特性_.docx

    自 PHP 5.4.0 版本起,PHP 引入了一种新的代码复用机制,称为 Traits。Traits 是一种为了解决单继承限制而设计的特性,它允许开发者在一个类中引入其他类或 Trait 中的方法,从而实现功能的组合。 Traits 本身不能...

    boost_1_69_0.tar.gz

    1. **编译时计算**:Boost.TypeTraits和Boost.Preprocessor库则允许在编译时进行类型检查和计算。 在下载并解压"boost_1_69_0.tar.gz"后,用户通常需要配置、编译和安装Boost库才能在项目中使用。这个过程可能涉及...

    boost_1_58_0.tar.gz

    Boost.TypeTraits库则提供了类型属性的检查和转换,有助于在编译时进行类型分析。 Boost库还包含了用于解决并发和并行编程问题的组件,如Boost.Asio,它是一个异步I/O库,支持网络通信、定时器和信号处理等功能,...

    C++内存池完整代码memory_pool.rar

    - **test.cpp**:这可能是测试代码,用于验证内存池的实现是否正确。 - **my_new.cpp 和 my_new.h**:这两个文件包含了自定义的新分配器的实现,其中my_new.h可能定义了内存分配的接口,而my_new.cpp实现了这些接口...

    Python库 | link_traits-1.0.3.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:link_traits-1.0.3.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    ubuntu//pcl-1.13.0

    sudo apt install build-essential cmake git libflann-dev libeigen3-dev libboost-all-dev libqhull-dev libusb-1.0-0-dev libopencv-dev libvtk6-dev ``` 3. 下载PCL源代码: ```bash git clone ...

    variant_access:https:docs.rsvariant_access_traits

    变体访问 一组特征和宏,用于基于C ++标准库中的std :: variant API为Rust枚举定义通用api基本用法考虑以下枚举: enum Enum { F1 ( i32 ), F2 ( bool )} 当然,我们可以直接使用字段名称和match语句使用此类枚举。...

    win_php_memcache.dll集合

    PHP 5.4进一步提升了性能,添加了 Traits 和 Short Array Syntax;PHP 5.5引入了OpCache,提升了脚本执行效率;PHP 5.6对一些废弃函数进行了移除,强化了安全特性;PHP 7.0进行了重大的语法和性能改进,引入了全新的...

    PHP 魔术变量和魔术函数详解_.docx

    Traits是用来实现代码复用的机制,允许在多个类中重用方法,但要注意trait方法和类方法之间的优先级和覆盖规则。 除了魔术变量,PHP还有魔术函数,如`__construct()`用于对象的构造,`__destruct()`用于对象销毁,`...

    boost-1-85-0.tar.gz.zip

    11. **编译时元编程库**:Boost.MPL(Meta-Programming Library)和Boost.TypeTraits允许在编译时进行计算和类型检查。 12. **程序选项库**:Boost.ProgramOptions帮助处理命令行参数和配置文件选项。 13. **信号...

    Scala_2.7.6_API_离线精简2009.0915_By_ScalaCn.com

    5. **特质(Traits)**:Scala的特质是介于接口和抽象类之间的一种结构,它可以包含实现代码,是实现多继承和代码重用的有效方式。 6. **函数式编程**:Scala支持丰富的函数式编程特性,如柯里化、尾递归、匿名函数...

    spatial_sp_traits:NSF项目中使用的功能和代码,

    "spatial_sp_traits"项目,根据标题和描述,似乎是一个基于R语言的项目,它专门用于处理和分析空间数据,可能与美国国家科学基金会(NSF)资助的UCR(University of California, Riverside)项目有关。这个项目可能...

Global site tag (gtag.js) - Google Analytics