- 浏览: 233738 次
- 性别:
- 来自: 昆明
文章分类
最新评论
-
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 1419详细的发布公告: http://www.dsource.org ... -
D新闻组里的天才代码
2008-03-30 21:26 3310超猛的代码,刚才逛新闻组刚看到的,随便记录一下。 出自: ... -
Ubuntu & D
2008-03-23 12:33 2430前几天 Ubuntu Linux 8.04 (Hardy) 刚 ... -
Dotmars.test 单元测试框架简介
2007-11-19 22:43 94D语言内置的 unittest关键字+assert 组成的单元 ... -
mixin 模拟多继承
2007-11-10 17:40 3714D1.0 代码 /** TupleMixin ... -
简单的 C to D 转换 Ruby 脚本
2007-10-24 22:06 4657今天晚上费了点脑筋写了一个简单的 C2D 转换脚本,大致实现了 ... -
D1.0代码模拟 __traits(hasMember, ...)
2007-10-08 23:12 5149通过1.0的代码完全模拟了 D 2.0 __traits(ha ... -
更好的C++——给C++使用者的D语言简介
2007-09-14 01:30 12311作为 C++ 狂热的粉丝, ... -
让D代码自己编译自己
2007-09-12 22:55 4802刚在 D语言的新闻组里看到了D模板&元编程顶尖高人 ... -
Dotmars 实例之:容器、迭代器与算法框架
2007-08-03 23:49 5716Dotmars 实例之:容器、迭代器与算法框架 这几天 Mr. ... -
基于 D 2.0 编译时反射的单元测试框架
2007-07-27 21:25 2839一个模仿 Ruby Test::Unit 的 Quick &a ... -
D 2.0 Const/Final/Invariant 概念简介
2007-07-24 22:55 5467D 2.0 Const/Final/Invariant 概 ... -
DotMars 版 Hello World
2007-06-05 02:17 8231DotMars 已经具有初步的样子了,特别发帖庆祝。 Dot ... -
关联数组字面值+函数字面值=支持任意类型的 switch
2007-05-19 23:29 4559刚才写字符串格式化的由于要处理所有内置类型,而且只有 Type ... -
.Net/Java 风格格式化字符串
2007-05-18 22:51 3627基础类库的东西看起来容易做起来难,今天花时间实现了一点点 . ... -
修改版 juno.com.base
2007-04-20 00:28 4319dsource 上的 juno 是一个很不错的 Windows ... -
C#-like 的 DLL 封装
2007-04-16 23:19 4418一个类似 C# 的 DllImport 实现,用于“半”动态加 ... -
简单的D语言 VIM 缩写插件
2007-04-13 15:45 3503昨晚我写了一个非常简单的 VIM 的D语言缩写插件,希望能让用 ... -
双向链表模板类
2007-04-07 02:03 3065参考 STL 实现的 Quick & Dirty 双向 ... -
用Rant自动化D语言程序构建
2007-03-31 13:54 3264上回说到 Rank 这个 Ruby 世界最广泛使用的构建工具在 ...
相关推荐
本文将深入探讨如何利用R语言和C#进行混合编程,并通过一个名为R(D)COMServer的组件实现这一目标。 #### 二、R(D)COMServer介绍 R(D)COMServer是由Vienna University of Technology和University of Vienna联合开发...
与C/C++等语言能够直接通过指针操作来实现内存的动态分配不同,VB 缺乏原生支持这种灵活的数组管理方式。这就意味着开发者在编写程序时可能会遇到如下的问题: 1. **数组大小预估困难**:在声明数组时,如果预先...
在D语言中,XML DOM允许程序员通过对象模型来访问和操作XML数据,从而实现读取、修改和创建XML文档。XML DOM为D语言开发者提供了一种结构化的访问方式,可以方便地遍历XML节点、查找特定信息、修改元素属性等。这在...
在VB011-求一元二次方程的根这个主题中,我们主要探讨的是如何使用Visual Basic(VB)编程语言来解决数学中的一元二次方程。一元二次方程是形如ax² + bx + c = 0的方程,其中a、b和c是常数,a不等于0。解决此类方程...
本文将详细介绍使用VC6.0 MFC编程语言实现串口通信的全过程,涵盖串口调试助手的编辑过程、新建工程、添加控件、编辑控件、编程步骤等方面的知识点。 一、串口调试助手编辑过程 在VC6.0 MFC中,新建一个MFC ...
VBA(Visual Basic for Applications)是Microsoft Office套件中用于自动化和编程的一种语言,它允许用户在Excel、Word等应用程序中编写自定义脚本,实现更复杂的功能。VBA字典对象是VBA中非常实用的数据结构之一,...
本文主要介绍如何使用Java语言结合第三方库`jacob.jar`来实现多个Word文档的合并功能。 #### 二、核心知识点解析 1. **Jacob库简介**: - Jacob (Java COM Bridge) 是一个开源库,它允许Java程序通过COM接口调用...
Java作为一种强大的编程语言,提供了多种方式来实现这个需求。本篇将深入探讨如何利用Java库JACOB进行Word到TXT的批量转换。 JACOB(Java COM Bridge)是一个Java到COM接口的桥梁,它允许Java程序调用Windows的COM...
工程使用的是基于对话框的程序,每个对话框为一个类,父类为CDialog,实现的一些功能都封装在类的函数中,体现了面向对象编程语言C++的特性。 导入ADO接口:在工程的stdafx.h文件里直接引入符号#import引入ADO库文件...
随着信息技术的发展,特别是Microsoft Office组件如Excel的强大功能以及Visual C++(VC)这样的高级编程语言的应用,可以有效地解决这一问题。本文旨在介绍如何利用VC结合ActiveX Data Objects (ADO)技术访问...
实现关系通常在面向对象语言中指的是接口或抽象类的实现。 6. **循环计算**: - 给定的VBScript程序段在Command1_Click事件中,当i=20时,x的值为x+i,即8+20,因此最后`x`的值为28,选项D是正确答案。 7. **微机...
例如,Delphi的Variant类型可以直接映射到Python的任意类型,这在跨语言交互中非常有用。 在调用Python代码时,可以使用TPythonEngine的Execute方法来运行Python脚本,或者通过ExecuteMethod来调用已定义的Python...
13. **ASP脚本语言**:ASP文件中可以设置默认脚本语言,但仍可使用其他脚本,选项D错误。 14. **VBScript特性**:VBScript只有一种数据类型,即Variant,选项A正确。VBScript中变量无需先声明即可使用,选项C错误,...
VB(Variant Blast)是一种在生物信息学领域中用于检测序列变异的工具,它结合了变体查询和BLAST(Basic Local Alignment Search Tool)的功能。在本案例中,我们讨论的是如何利用VB对hapx文件进行操作,寻找直系...
### WordToHtml 转换工具知识点解析 #### 一、概述 ...通过 Java 编程语言和 `com.jacob` 库的强大功能,实现了高效的文件转换任务。对于需要处理大量 Word 文档的用户来说,这是一个非常实用的工具。
Matlab是计算机视觉和图像处理领域中常用的开发语言, mặc dù它自带了图像处理和计算机视觉的许多功能,但是术业有专攻,在进行深入的视觉算法研究的时候Matlab的自带功能难免会不够用。因此,我们需要借助一些...
SQL 语言主要包括数据定义语言(DDL)、数据操纵语言(DML)和数据控制语言(DCL),不涉及关系规范化。 ### 8. Java 中字符串的操作 - **知识点**:Java 提供了 `String` 和 `StringBuffer` 类来处理字符串。 - *...
2. **SQL 语言**:SQL中的`GRANT`和`REVOKE`语句用于实现数据库的安全性控制,它们分别用于赋予和撤销用户对数据库对象的访问权限。 3. **数据模型**:数据模型的三个要素是数据结构、数据操作和数据完整性约束。...
我们将通过两种方式来实现这个目标,分别是使用 Java 流读取 Word 内容和使用 Jacob 读取 Word 内容。 使用 Java 流读取 Word 内容 在第一个示例中,我们使用 Java 流来读取 Word 文档的内容。我们首先需要引入...