C++03 3.9-10:

1

Arithmetic types (3.9.1), enumeration types, pointer types, and pointer to member types (3.9.2), and cv-qualified versions of these types (3.9.3) are collectively called scalar types. Scalar types, POD-struct types, POD-union types (clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called POD types.

 

As we all knows the pointer to member may not be cast into void* (GCC is OK but it's a special case anyway), according to the standrad we can store the pointer to member to a char buffer though. Unfortunately, the size of "pointer to member" is implementation defined, so we still need some hack for different compilers.

here's a table for sizeof(pointer to member) for some compilers

(http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Compiler            Options     Single  Multi   Virtual Unknown
    MSVC                        4       8       12      16
    MSVC            /vmg        16#     16#     16#     16
    MSVC            /vmg /vmm   8#      8#      --      8
    Intel_IA32                  4       8       12      16
    Intel_IA32      /vmg /vmm   4       8       --      8
    Intel_Itanium               8       12      16      20
    G++                         8       8       8       8
    Comeau                      8       8       8       8
    DMC                         4       4       4       4
    BCC32                       12      12      12      12
    BCC32           /Vmd        4       8       12      12
    WCL386                      12      12      12      12
    CodeWarrior                 12      12      12      12
    XLC                         20      20      20      20
    DMC small                   2       2       2       2
    medium                      4       4       4       4
    WCL small                   6       6       6       6
    compact                     6       6       6       6
    medium                      8       8       8       8
    large                       8       8       8       8

the original article implement each compiler's pointer to member mechanism, which I believe is insane, it's definitely not a good way to write portable codes.here's what I'm doing (code snippet).

所以pointer to member 可以被保存在byte array 里面再被解出来.这对于做delegate很有帮助.这是我目前使用的方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Delegate
{
public:
//per-compiler constant, or use a max enough size for all compilers
#if COMPILER == COMPILER_MSVC
    static const size_t MAX_POINTER2MEMBER_SIZE = 16;
#elif COMPILER == COMPILER_GNUC
    static const size_t MAX_POINTER2MEMBER_SIZE = 8;
#else
    static const size_t MAX_POINTER2MEMBER_SIZE = 20;
#endif
 
    void* mPtr;
    char  mMemberRaw[MAX_POINTER2MEMBER_SIZE ];
 
    //store the pointer to member to a byte buffer
    template <typename T>
    explicit Delegate(T* ptr, void (T::*func)(void*) )
    {
        assertsizeof(func) <= MAX_SIZE );
        ::memset(mMemberRaw, 0, MAX_SIZE);
        ::memcpy(mMemberRaw, &func, sizeof(func) );
    }
};
 
 
//invoke function: extract the "pointer to member" from the byte buffer
{
    ...
    typedef void (T::*TMemberFn)(void*);
    TMemberFn TFn = NULL;
    ::memcpy(&TFn, mMemberRaw, sizeof(TFn) );
    ( ((T*)mPtr)->*TFn )( data);
}

there's a very efficient way to do the delegate :

http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates

他也是用模板函数,但不同的是把函数地址作为模板参数.本来打算改用这个方法的.但是唯一的缺点就是需要显式指定模板参数<>来实例化, 而构造函数只能通过TAD来套用模板参数,不能显式指定...所以他用的是一个静态模板函数来构造一个对象

1
delegate d = delegate::frommember<T,&T::func>( pOjb); //这样稍微有点恶心.

而我使用的方式虽然多了一个char[], 有一点点额外的内存开销和运行时开销,但是大多数情况下几乎可以忽略不计.

主要是可以通过Template Arugment Deduction 直接创建delegate, 比如:

1
Delegate d(pObj, &CLASS::function);

所以考虑了一下,决定暂时不用他的那种方法(用起来稍微不方便,但是效率非常高).以后看情况再考虑要不要改.

另外,作为一个C++程序猿, 个人觉得"数据绑定", "反射","代理",这些使用时尽量谨慎, 不可滥用. 除了在event/msg 和 UI/Tools的极少数地方要用以外,其他地方还是尽量不要用为好. 最近把数据绑定框架做了简单重构, 幸好用到的地方不多(主要是编辑器在用), 要不然重构就哭了. 目前还没有反射,暂时不需要, 以后需要时再加.最好是另外封装,不影响现在的代码.

[百度空间] [note] pointer to member is a POD type的更多相关文章

  1. jquery-plugin-biggerLink,highLight-层加亮_andy 阳光生活_百度空间

    How to get the xpath by clicking an html element How to get the xpath by clicking an html element Qu ...

  2. Android手机无法访问百度空间的解决办法

    本文网址:http://www.cnblogs.com/tunnel213/p/4301165.html 现象: 百度“JavaScript函数高级”后找到一篇文章,百度空间的,无法查看: 配置: 三 ...

  3. document.domain - JavaScript的同源策略问题:错误信息:Permission denied to access property 'document'_eecc00_百度空间

    document.domain - JavaScript的同源策略问题:错误信息:Permission denied to access property 'document'_eecc00_百度空间 ...

  4. memcached vs MySQL Memory engine table 速度比较_XMPP Jabber即时通讯开发实践_百度空间

    memcached vs MySQL Memory engine table 速度比较_XMPP Jabber即时通讯开发实践_百度空间 memcached vs MySQL Memory engin ...

  5. 提高mysql memory(heap) engine内存性能的开源补丁_XMPP Jabber即时通讯开发实践_百度空间

    提高mysql memory(heap) engine内存性能的开源补丁_XMPP Jabber即时通讯开发实践_百度空间 提高mysql memory(heap) engine内存性能的开源补丁

  6. sort 使用 tab键 作为 分隔符_人生如梦_百度空间

    sort 使用 tab键 作为 分隔符_人生如梦_百度空间 sort 使用 tab键 作为 分隔符 For some reason "\t" doesn't work right, ...

  7. centos5.5字体为方块问题的解决_深入学习编程_百度空间

    centos5.5字体为方块问题的解决_深入学习编程_百度空间 centos5.5字体为方块问题的解决 一.yum -y install fonts-chinese二.yum -y install f ...

  8. 毕业论文评审意见、导师意见范文、模板_Smile~风_百度空间

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  9. Attribute name invalid for tag form according to TLD异常解决办法_gaigai_百度空间

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

随机推荐

  1. JS下高效拼装字符串的几种方法比较与测试代码

    在使用Ajax提交信息时,我可能常常需要拼装一些比较大的字符串通过XmlHttp来完成POST提交.尽管提交这样大的信息的做法看起来并不优雅,但有时我们可能不得不面对这样的需求.那么JavaScrip ...

  2. MySQL自用脚本(不定期更新)

    查询指定SQL的trace信息 mysql -uUSER -pPWD -hHOST -e "\ use ins_tc_prd; \ set session optimizer_trace=' ...

  3. AngularJs记录学习01

    <!doctype html> <html ng-app="myapp"> <head> <meta http-equiv="C ...

  4. XAML(3) - 附带属性

    WPF元素也可以从父元素中获得特性.例如,如果Button元素为了Canvas元素中,按钮的Top和Lef属性把父元素的名称作为前缀.这种属性成为附带属性: <Canvas> <Bu ...

  5. 整齐地输出n的平方,立方

    初学C语言,有许多搞不明白的地方.编程,最重要的就是实践.今天,我偶然间看到书上的练习,做了一个能整齐地输出n,n的平方,n的立方的小程序.首先,我先用伪代码设计程序: 提示用户输入表格上限,下限或退 ...

  6. ViewSwitcher使用范例

    一.简介 ViewSwitcher适用于两个视图带动画效果的切换.这里实现两个视图切换的功能,并附带滑屏效果. 二.截图 二.范例代码 带动画效果的切换视图一和视图二. xml <ViewSwi ...

  7. iOS学习之UI可视化编程-StoryBoard

    一.StoryBoard与xib 对比: 相同点:都属于IB编程的方式,可以快速构建GUI. 不同点:xib侧重于单文件(单独的控制器或者视图)编辑,storyboard侧重于多页面关联.storyb ...

  8. VHDL----基础知识1

    摘要: 打算分几篇,来理清VHDL的基础知识 ----------------------------------------------------------------------------- ...

  9. Error (10028): Can't resolve multiple constant drivers for net "out2" at shiyan.v(14)解决办法

    //Error(10028):Can't resolve multiple constant drivers for net “ ” at **.v //两个进程里都有同一个条件判断的话,会产生并行信 ...

  10. 62.在cdc文件上某些例化模块看不到的原因

    比如在顶层文件中,例化了几个模块,综合后打开cdc文件,会在structure/net中少几个例化模块,即看不到,但在顶层文件中还是存在的,只是ISE软件综合的问题而已,原因是在顶层或子模块中,有些应 ...