- 浏览: 230703 次
- 性别:
- 来自: 昆明
文章分类
最新评论
-
beiyangshuishi:
确实挺幽默的,太能恶搞了。不过这也让我想起日本的一则广告宣纸的 ...
一对活宝—— MySQL & PostgreSQL -
ShiningRay:
稍微看了vcf的api,比wxwidgets要干净得多
VCF 库的搞笑提示 -
Colorful:
Wow, this is amazing.
D语言 struct constrcutor 的 bug -
oldrev:
楼下,当时的 TRAC 确实说是要 py 2.4 的
出色的开源项目管理软件——Redmine -
jusdao:
...Trac可以用python2.5啊,没有说必须用2.4的 ...
出色的开源项目管理软件——Redmine
boost.variant 是安全、范型、基于栈的可识别联合容器,下面的代码是其在D语言中的等价实现。借助D语言强大的元编程能力,其与C++的版本相比,代码清晰,对类型安全有更大的保证。
这个实现可以稍稍优化一下,因为ValueType是在编译期可以知道的,所以可以用IndexOf确定它在TList中的位置,直接和which判断就行了,不用再调用type()函数。
我就是知道 assert 可以被屏蔽掉,所以才偷了个懒....
另外断言只在debug环境下有效,如果是不兼容的类型,cast结果会是空指针,这时可能会出现一个段错误了。
对阿,这里应该用异常还是 assert 应该再仔细研究一下。
不过这个opCast只能转到一种类型,可以自己实现多种类型的转换,当然也就用不了cast了:
C++ 的用户自定义类型转换操作符可以实现隐式转换,如:
这个特性虽然方便但也很容易引起难以发现的 bug
这个实现可以稍稍优化一下,因为ValueType是在编译期可以知道的,所以可以用IndexOf确定它在TList中的位置,直接和which判断就行了,不用再调用type()函数。
另外断言只在debug环境下有效,如果是不兼容的类型,cast结果会是空指针,这时可能会出现一个段错误了。
- boost.variant 文档:http://www.boost.org/doc/html/variant.html
- boost.any 和 boost.variant 的区别与比较: http://www.boost.org/doc/html/variant/misc.html#variant.versus-any
cpp 代码
- // Module: variant.d
- // Author: Oldrev (wstring#AT#gmail.com)
- // License: BSD
- module variant;
- import std.typetuple;
- import std.traits;
- import std.stdio;
- private template MaxSizeImp(T, V...)
- {
- static if(V.length > 0)
- private const int tailResult = MaxSizeImp!(V).result;
- else
- private const int tailResult = T.sizeof;
- public const int result = T.sizeof > tailResult ? T.sizeof : tailResult;
- };
- private template MaxSize(TList...)
- {
- const int MaxSize = MaxSizeImp!(TList).result;
- }
- struct Variant(TList...)
- {
- public alias TList TypeList;
- public alias Variant!(TypeList) SelfType;
- private alias ubyte[MaxSize!(TypeList)] Holder;
- private Holder m_held;
- private int m_which = -1;
- public int which()
- {
- return m_which;
- }
- public SelfType assign(ValueType)(ValueType val)
- {
- static if(is(ValueType == SelfType))
- {
- m_held[] = val.m_held[];
- m_which = which;
- }
- else
- {
- const int i = IndexOf!(ValueType, TypeList);
- static assert(i >= 0);
- ValueType* heldPtr = cast(ValueType*)m_held.ptr;
- *heldPtr = val;
- m_which = i;
- }
- return *this;
- }
- public SelfType opAssign(ValueType)(ValueType rhs)
- {
- return assign!(ValueType)(rhs);
- }
- public bool opEquals(ValueType)(ValueType rhs)
- {
- assert(!empty);
- static if(is(ValueType == SelfType))
- {
- foreach(T; TypeList)
- {
- const int i = IndexOf!(T, TypeList);
- if(i == which)
- {
- return (rhs.which == which) && (get!(T) == rhs.get!(T));
- }
- }
- }
- else
- {
- const int i = IndexOf!(ValueType, TypeList);
- static assert(i >= 0);
- return get!(ValueType)() == rhs;
- }
- }
- public int opCmp(ValueType)(ValueType rhs)
- {
- if(rhs == *this)return 0;
- static if(is(ValueType == SelfType))
- {
- foreach(T; TypeList)
- {
- const int i = IndexOf!(T, TypeList);
- if((i == which) && (rhs.which == which))
- {
- return get!(T) < rhs.get!(T) ? -1 : 1;
- }
- }
- }
- else
- {
- const int i = IndexOf!(ValueType, TypeList);
- static assert(i >= 0);
- return get!(ValueType)() < rhs ? -1 : 1;
- }
- }
- public TypeInfo type()
- {
- foreach(T; TypeList)
- {
- const int i = IndexOf!(T, TypeList);
- if(i == which)
- {
- return typeid(TypeList[i]);
- }
- }
- }
- public ValueType get(ValueType)()
- {
- assert(typeid(ValueType) == type);
- return *(cast(ValueType*)m_held.ptr);
- }
- public bool empty()
- {
- return m_which < 0;
- }
- public void swap(inout SelfType var)
- {
- Holder h;
- h[] = m_held;
- int w = which;
- m_held[] = var.m_held;
- m_which = var.which;
- var.m_held[] = h;
- var.m_which = w;
- }
- public static SelfType opCall(ValueType)(ValueType val)
- {
- SelfType var;
- var = val;
- return var;
- }
- }
- void main()
- {
- class Foo
- {
- public:
- int n = 0;
- int x = 0;
- int y = 0;
- int z = 0;
- Foo opAssign(int rhs)
- {
- x = rhs;
- y = rhs;
- z = rhs;
- return this;
- }
- }
- struct Bar
- {
- public:
- int x = 0;
- int y = 1;
- int z = 2;
- }
- Variant!(double, int, char[], Foo, Bar) v = 2; // DMD 0.177 new feature
- assert(v == 2);
- assert(v <= 2);
- v = 2.22;
- assert(v == 2.22);
- assert(v.type == typeid(double));
- v = new Foo;
- assert(v.type == typeid(Foo));
- v.get!(Foo)() = 2;
- assert(v.get!(Foo)().z == 2);
- typeof(v) v2 = v;
- assert(v2 == v);
- v = "Foobar".dup;
- assert(v == "Foobar".dup);
- v.swap(v2);
- assert(v2.get!(char[])() == "Foobar");
- Bar b;
- b.x = 10;
- v = b;
- assert(v.get!(Bar)().x == 10);
- }
评论
7 楼
oldrev
2007-03-16
引用
这个实现可以稍稍优化一下,因为ValueType是在编译期可以知道的,所以可以用IndexOf确定它在TList中的位置,直接和which判断就行了,不用再调用type()函数。
我就是知道 assert 可以被屏蔽掉,所以才偷了个懒....
引用
另外断言只在debug环境下有效,如果是不兼容的类型,cast结果会是空指针,这时可能会出现一个段错误了。
对阿,这里应该用异常还是 assert 应该再仔细研究一下。
6 楼
oldrev
2007-03-16
引用
不过这个opCast只能转到一种类型,可以自己实现多种类型的转换,当然也就用不了cast了:
C++ 的用户自定义类型转换操作符可以实现隐式转换,如:
operator double() const {...}
这个特性虽然方便但也很容易引起难以发现的 bug
5 楼
qiezi
2007-03-16
public ValueType get(ValueType)() { assert(typeid(ValueType) == type); return *(cast(ValueType*)m_held.ptr); }
这个实现可以稍稍优化一下,因为ValueType是在编译期可以知道的,所以可以用IndexOf确定它在TList中的位置,直接和which判断就行了,不用再调用type()函数。
另外断言只在debug环境下有效,如果是不兼容的类型,cast结果会是空指针,这时可能会出现一个段错误了。
4 楼
qiezi
2007-03-16
不过这个opCast只能转到一种类型,可以自己实现多种类型的转换,当然也就用不了cast了:
import std.stdio; class Foo{ int convert(T:int)(){return 3;} long convert(T:long)(){return 4;} } void main(){ Foo f = new Foo; writefln(f.convert!(int)); writefln(f.convert!(long)); }
3 楼
qiezi
2007-03-16
可以呀,opCast就是了。。
http://digitalmars.com/d/operatoroverloading.html
http://digitalmars.com/d/operatoroverloading.html
2 楼
oldrev
2007-03-15
为什么D不能重载类型转换操作符呢
1 楼
ideage
2007-03-07
这个好东西也可以贡献到Tango了!发布到火星吧!
发表评论
-
Tango 0.99.7 Dominik 今天放出
2008-07-25 12:16 1388详细的发布公告: http://www.dsource.org ... -
D新闻组里的天才代码
2008-03-30 21:26 3272超猛的代码,刚才逛新闻组刚看到的,随便记录一下。 出自: ... -
Ubuntu & D
2008-03-23 12:33 2394前几天 Ubuntu Linux 8.04 (Hardy) 刚 ... -
Dotmars.test 单元测试框架简介
2007-11-19 22:43 94D语言内置的 unittest关键字+assert 组成的单元 ... -
mixin 模拟多继承
2007-11-10 17:40 3661D1.0 代码 /** TupleMixin ... -
简单的 C to D 转换 Ruby 脚本
2007-10-24 22:06 4602今天晚上费了点脑筋写了一个简单的 C2D 转换脚本,大致实现了 ... -
D1.0代码模拟 __traits(hasMember, ...)
2007-10-08 23:12 5120通过1.0的代码完全模拟了 D 2.0 __traits(ha ... -
更好的C++——给C++使用者的D语言简介
2007-09-14 01:30 12228作为 C++ 狂热的粉丝, ... -
让D代码自己编译自己
2007-09-12 22:55 4759刚在 D语言的新闻组里看到了D模板&元编程顶尖高人 ... -
Dotmars 实例之:容器、迭代器与算法框架
2007-08-03 23:49 5682Dotmars 实例之:容器、迭代器与算法框架 这几天 Mr. ... -
基于 D 2.0 编译时反射的单元测试框架
2007-07-27 21:25 2798一个模仿 Ruby Test::Unit 的 Quick &a ... -
D 2.0 Const/Final/Invariant 概念简介
2007-07-24 22:55 5430D 2.0 Const/Final/Invariant 概 ... -
DotMars 版 Hello World
2007-06-05 02:17 8193DotMars 已经具有初步的样子了,特别发帖庆祝。 Dot ... -
关联数组字面值+函数字面值=支持任意类型的 switch
2007-05-19 23:29 4523刚才写字符串格式化的由于要处理所有内置类型,而且只有 Type ... -
.Net/Java 风格格式化字符串
2007-05-18 22:51 3594基础类库的东西看起来容易做起来难,今天花时间实现了一点点 . ... -
修改版 juno.com.base
2007-04-20 00:28 4287dsource 上的 juno 是一个很不错的 Windows ... -
C#-like 的 DLL 封装
2007-04-16 23:19 4376一个类似 C# 的 DllImport 实现,用于“半”动态加 ... -
简单的D语言 VIM 缩写插件
2007-04-13 15:45 3457昨晚我写了一个非常简单的 VIM 的D语言缩写插件,希望能让用 ... -
双向链表模板类
2007-04-07 02:03 3024参考 STL 实现的 Quick & Dirty 双向 ... -
用Rant自动化D语言程序构建
2007-03-31 13:54 3202上回说到 Rank 这个 Ruby 世界最广泛使用的构建工具在 ...
相关推荐
C语言头文件 VARIANTC语言头文件 VARIANTC语言头文件 VARIANTC语言头文件 VARIANTC语言头文件 VARIANTC语言头文件 VARIANTC语言头文件 VARIANTC语言头文件 VARIANTC语言头文件 VARIANTC语言头文件 VARIANTC语言...
TIA博途_通过Variant操作数组实现华氏度数据批量转换成摄氏度的具体方法
MOVE_BLK_VARIANT范例
实际上,Variant类型对Pascal语言有普遍而深入的影响,Delphi 控件库中与OLE 无关的地方也使用到这种类型。 Variant变量没有类型 一般说来,你可以用Variant 变量存储任何数据类型,对它执行各种操作和类型转换...
C++ 变体类实现类及资料包含source code
一个Variant类型转换成CString的函数,调试过,可以用。
variant, Eggs.Variant 是 C 11/14/17 泛型,类型安全,可以识别的联合 Eggs.Variant简介英镑 Eggs.Variant 为英镑 C 11/14/17 型,类型安全,可以区分。 参见 ...要求库需要标准一致的实现;一些
variant 用法,包括函数,变量如何使用
详细讲述数据类型VARIANT的用法及SAFEARRAY的用法,可以通过此类型在组件中传递数据
AltiumDesigner20装配变量Variant使用说明 .pdf
variant_t的详细用法解说 COleDateTime vartodate(const _variant_t& var) { COleDateTime value; switch (var.vt) { case VT_DATE: { value = var.date; } break; case VT_EMPTY:
将 _variant_t 类型的变量,转换成任意类型
网上下载的一些Variant操作函数,有需要的下载研究一下
有个麻烦的事情就是_variant_t变量的使用
一款高效的Vue低代码表单、工作流表单,包含表单设计器和表单渲染器,可视化设计,一键生成源码,享受更多摸鱼时间
python库。 资源全名:variant_normalizer-0.1.3-py3-none-any.whl
博文链接:https://kristen-wang2008.iteye.com/blog/174270
Introduction to Variant Configuration with an example model
利用Variant变量用DELPHI操作EXCEL.zip
这段程序可以把byte[](字节数组)转换为VARIANT类型。